当前位置: 首页 > 知识库问答 >
问题:

多线程环境中带静态引用/对象的同步块

庞瀚
2023-03-14

公共类栏实现可运行{

@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中的任何线程通过同步块获取锁(例如T1获取)时,t2T3将处于阻塞状态,但同时允许其他线程T4T5T6并发执行。

公共类栏实现可运行{

    @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释放锁。

公共类栏实现可运行{

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();

}

synchronized块(synchronized(NUM))中的静态引用NUM是否等同于synchronized(bar.class)

共有1个答案

南宫凡
2023-03-14

在synchronized块中使用静态引用/对象会有什么影响(如示例#3)

静态对象在线程之间共享,因此当一个线程获得锁时,所有线程都将阻塞。这意味着如果t1在同步块内,那么t2、t3、…、t6被阻塞。

但是在你提供的代码中有一个诀窍。NUM++这将创建一个新的NUM对象,因为Integer类是不可变的。所以会发生什么,假设t1获得锁并进入同步块。现在,t1执行num++。现在可能会发生很多情况。

    null

假设非静态对象不在类条的实例之间共享,因此synchronized块中只能有t1、t2、t3的一个线程。t4、t5、T6也是如此。但是,如果是共享的,则具有与静态对象相同的效果。

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

如果你不改变NUM,就像我在第一个问题的答案中解释的那样

 类似资料:
  • 现在我的问题是:关键字对这种情况有用吗?

  • 问题内容: 任何人都可以解释以下语句吗……“静态同步方法和非静态同步方法不会互相阻塞-它们可以同时运行” 问题答案: 锁定对象在静态方法和非静态方法上有所不同。静态方法将Class对象用作锁(锁obj:),而非静态方法将实例对象用作锁,此时方法的调用已绑定到该对象(锁obj:)。

  • 如果我有多个线程,每个线程使用injector获取EntityManager对象,每个线程使用em对象选择其他类对象的列表。准备好在for循环中使用。 如果一个线程首先完成并调用clear(),这会影响其他线程吗?比如for循环会有异常? 谢谢你。

  • 问题内容: 有一个简单的愚蠢问题困扰着我,并在我脑海中提出了几个论点。我想排除所有对以下问题的怀疑。 假设有五个线程同时执行一个调用。 线程1调用。 当线程1位于第1节中时,线程2调用。 那么线程1将会发生什么?会进入睡眠状态吗? 当线程1获得机会时,它将从暂停的第1节继续执行吗? 在所有五个线程之间共享一个相同的线程时,该如何处理? 是否有可能互换多个线程发送的消息? 问题答案: 汉斯·帕桑(H

  • 尝试可视化和理解同步。 对同步块使用静态锁定对象(代码a)和非静态锁定对象(代码B)之间有什么区别 它在实际应用中有什么不同 一方会有哪些陷阱而另一方不会 确定使用哪一个的标准是什么 代码A 代码B 笔记 上面的代码显示了构造函数,但是您可以讨论静态方法和非静态方法中的行为是如何不同的。另外,在同步块修改静态成员变量时使用静态锁是否有利? 我已经看过了这个问题的答案,但是还不清楚不同的使用场景是什

  • 我已经面临这个问题很多天了,请帮我解决。我正在使用线程同步实现生产者-消费者示例。我在这个传统节目中做了一些调整。我没有只使用一个队列对象,而是使用了两个队列对象。但程序不起作用。。(PS-我知道我可以通过只使用队列的一个对象来让这个程序工作,但如果我想使用两个队列对象呢??) 类队列{ } 类生产者实现Runnable{ } 类消费者实现可运行{ } 公共类测试队列{ }