【问题标题】:something strange happen with synchronized (Test2.class)同步(Test2.class)发生了一些奇怪的事情
【发布时间】:2017-01-09 10:09:25
【问题描述】:
public class Test2 {
    static int count;
    public static void main(String[] args) {
        final Test2 t1 = new Test2();
        final Test2 t2 = new Test2();

        new Thread(new Runnable() {

            @Override
            public void run() {
                t1.foo();
            }
        }).start();

        new Thread(new Runnable() {

            @Override
            public void run() {
                t1.bar();
            }
        }).start();

        new Thread(new Runnable() {

            @Override
            public void run() {
                t2.foo();
            }
        }).start();
    }
    public static synchronized void foo() {
        synchronized (Test2.class) {
            System.out.println("run bar"+count++);
            try {
                Thread.sleep(100000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    public static synchronized void bar() {
        System.out.println("run bar");
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

上面是我尝试过的代码。当我在一个同步的类(Test2.class)中编写所有代码时,我发现发生了一些奇怪的事情。在调用 foo() 方法后,我无法立即调用 bar() 方法。我认为它锁定了同一个对象。如何解释这个奇怪的事情。

【问题讨论】:

    标签: java multithreading static java-threads synchronized-block


    【解决方案1】:

    您的代码启动的所有 3 个线程都在 Test2 类上获取相同的锁。当你写一个以

    开头的方法时
    static synchronized
    

    这意味着它必须获取类对象上的锁。

    foo 方法中的同步块是多余的。它指定使用与使用静态同步相同的类来锁定。由于内在锁是可重入的,这不会导致问题。

    无论如何,您的每个线程都会获取锁,运行到完成,然后释放锁。由于您锁定的是类而不是实例,因此线程使用哪个 Test2 实例并不重要,它们仍然获取相同的锁并一次执行一个。

    当我运行它时,我得到了以下输出:

    c:\Users\ndh>java Test2
    run bar0
    run bar1
    run bar
    

    这些线程的运行顺序取决于调度程序。猜测调用 t1.foo 的 Runnable 抢占先机似乎是合理的——因为它是首先创建和启动的,它可能有一个窗口,它不会有任何竞争获取锁。

    【讨论】:

      猜你喜欢
      • 2011-12-05
      • 2021-09-25
      • 2011-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-16
      • 1970-01-01
      相关资源
      最近更新 更多