gpt4 book ai didi

java - 多线程环境中具有静态引用/对象的同步块(synchronized block)

转载 作者:行者123 更新时间:2023-12-01 22:31:59 25 4
gpt4 key购买 nike

虽然这个问题可能会在SO上被问几次(主要以 this 与 Synchronized block 中的 Bar.clas 的形式),但我不清楚类的静态引用/对象的同步(第三个示例) )这个问题。请看下面的 Java 示例:

  1. 示例#1 - synchronized阻止 this关键字

    公共(public)类 Bar 实现 Runnable {

    @Override
    public void run() {
    objectLock();
    }

    public void objectLock() {

    synchronized(this) {
    System.out.println(Thread.currentThread().getName());
    System.out.println("synchronized block " + Thread.currentThread().getName());
    System.out.println("synchronized block " + Thread.currentThread().getName() + " end");
    }
    }

    public static void main(String[] args) {
    Bar b1 = new Bar();
    Thread t1 = new Thread(b1);
    Thread t2 = new Thread(b1);
    Thread t3 = new Thread(b1);

    Bar b2 = new Bar();
    Thread t4 = new Thread(b2);
    Thread t5 = new Thread(b2);
    Thread t6 = new Thread(b2);

    t1.setName("t1");
    t2.setName("t2");
    t3.setName("t3");
    t4.setName("t4");
    t5.setName("t5");
    t6.setName("t6");


    t1.start();
    t2.start();
    t3.start();

    t4.start();
    t5.start();
    t6.start();

    }

    }

结果:当任何来自 t1,t2,t3 的线程时通过同步块(synchronized block)获取锁(例如t1获取),然后t2t3将处于阻塞状态,但同时其他线程t4 , t5t6允许同时执行。

  • 示例#2 - synchronized阻止 Bar.class

    公共(public)类 Bar 实现 Runnable {

        @Override
    public void run() {
    objectLock();
    }

    public void objectLock() {

    synchronized(Bar.class) {
    System.out.println(Thread.currentThread().getName());
    System.out.println("synchronized block " + Thread.currentThread().getName());
    System.out.println("synchronized block " + Thread.currentThread().getName() + " end");
    }
    }

    public static void main(String[] args) {
    Bar b1 = new Bar();
    Thread t1 = new Thread(b1);
    Thread t2 = new Thread(b1);
    Thread t3 = new Thread(b1);

    Bar b2 = new Bar();
    Thread t4 = new Thread(b2);
    Thread t5 = new Thread(b2);
    Thread t6 = new Thread(b2);

    t1.setName("t1");
    t2.setName("t2");
    t3.setName("t3");
    t4.setName("t4");
    t5.setName("t5");
    t6.setName("t6");


    t1.start();
    t2.start();
    t3.start();

    t4.start();
    t5.start();
    t6.start();

    }
    }
  • 结果: Bar 的任何实例中只有一个线程类,将获取锁(例如 t1 获取锁),并且所有其他线程( t2,t3...t6 )将被阻塞,直到 t1释放锁。

  • 示例#3 - synchronized阻止 static 引用/对象
  • 公共(public)类 Bar 实现 Runnable {

    private static  Integer NUM=new Integer(5);

    @Override
    public void run() {
    objectLock();
    }

    public void objectLock() {

    synchronized(NUM) {
    System.out.println(Thread.currentThread().getName());
    System.out.println(NUM++);
    System.out.println("synchronized block " + Thread.currentThread().getName());
    System.out.println("synchronized block " + Thread.currentThread().getName() + " end");
    }
    }

    public static void main(String[] args) {
    Bar b1 = new Bar();
    Thread t1 = new Thread(b1);
    Thread t2 = new Thread(b1);
    Thread t3 = new Thread(b1);

    Bar b2 = new Bar();
    Thread t4 = new Thread(b2);
    Thread t5 = new Thread(b2);
    Thread t6 = new Thread(b2);

    t1.setName("t1");
    t2.setName("t2");
    t3.setName("t3");
    t4.setName("t4");
    t5.setName("t5");
    t6.setName("t6");


    t1.start();
    t2.start();
    t3.start();

    t4.start();
    t5.start();
    t6.start();

    }

    }

    问题:

    1. 使用 static 会产生什么效果? synchronized 中的引用/对象 block (如示例#3)

    2. synchronized 中使用非静态引用/对象会产生什么效果?阻止。

    3. 静态引用 NUM 也是如此在同步块(synchronized block)( synchronized(NUM) )中相当于 synchronized(Bar.class)

    最佳答案

    在同步块(synchronized block)中使用静态引用/对象会产生什么效果(如示例#3)

    静态对象在线程之间共享,因此当一个线程获取锁时,所有线程都会阻塞。 这意味着如果 t1 在同步块(synchronized block)内,则 t2、t3、...、t6 会被阻塞。

    但是您提供的代码中有一个技巧。 NUM++ 这将创建一个新的 NUM 对象,因为 Integer 类是不可变的。那么会发生什么,假设 t1 获取锁并进入同步块(synchronized block)。现在,t1 执行 NUM++。现在可能会发生很多情况。

    1. 如果在执行 Num++ 之前另一个线程被阻塞,则该线程将保持阻塞状态,直到 t1 退出同步块(synchronized block)。
    2. 如果线程没有被阻塞(比如 t2)并且 Num++ 由 t1 执行,那么 t2 将不会阻塞,因为 Num 现在是一个新的 Integer。因此锁是不同的t2 进入为新 Integer 获取锁的 block 。

    所有线程都可能发生同样的故事。 事实上,所有线程同时处于同步块(synchronized block)中是可能的。

    在同步块(synchronized block)中使用非静态引用/对象会产生什么效果。

    假设 Bar 类的实例之间不共享非静态对象,则同步块(synchronized block)中只能有 t1、t2、t3 一个线程。 t4、t5、t6 类似。但是,如果它是共享的,则与静态对象具有相同的效果。

    同步块(synchronized block)中的静态引用 NUM (synchronized(NUM)) 是否等同于 synchronized(Bar.class) ?

    如果你不按照我在第一个问题的答案中解释的那样更改 NUM

    关于java - 多线程环境中具有静态引用/对象的同步块(synchronized block),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27561501/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com