调用同步方法的顺序

时间:2016-08-20 09:53:17

标签: java multithreading

我相信,这是一个简单的问题,但我仍然不能自己解决这个问题。说,我有以下代码。

Runnable objectRunnable = new Runnable() {
    void run() {
          synchronized(object) {
              for (int i = 0; i < 5; i++) {
                  System.out.println("it's runnable");
                  Thread.sleep(100); 
              }
          }
    }
};

void doSomething() {
    synchronized(object) {
        for (int i = 0; i < 5; i++) {
            System.out.println("it's doSomething");
            Thread.sleep(100);
        }
    }
}

synchronized (object) {
    new Thread(objectRunnable).start();
}
object.doSomething();

所以,输出就像

it's doSomething
it's doSomething
it's doSomething
it's doSomething
it's doSomething
it's runnable
it's runnable
it's runnable
it's runnable
it's runnable

问题是为什么doSomething()在线程之前发生了?此外,如果我在同步块之后多次调用对象方法,则它们都会被随后调用,然后只有程序返回到线程的内容。如果我用同步块替换那个线程调用行,比如调用一些模拟对象方法,那么一切正常,并按指定顺序进行。

同步对象本身的方法在执行此对象的任何线程之前是否具有某种优先级执行?

2 个答案:

答案 0 :(得分:2)

因为主线程是第一个获得锁定的线程。它可能是生成的线程,你只是不能确定,虽然这不太可能,因为调用start()后线程实际开始运行需要一些时间。

关于你的其余问题,答案太过模糊了。

答案 1 :(得分:1)

你在这里遇到的是一个竞争条件:由于创建synchronized (object),你的runnable在启动时在监视器上等待被阻塞。一旦创建runnable的线程释放了监视器,带有runnable的新创建的线程就没有机会抓住它,因为同一个线程在doSomething()方法中再次重新输入它。

如果您在致电Thread.sleep(100);

之前添加了对object.doSomething()的来电
synchronized (object) {
    new Thread(objectRunnable).start();
}
Thread.sleep(100); // <<== Add this line
object.doSomething();

打印输出的顺序将反转(demo)。

it's runnable
it's runnable
it's runnable
it's runnable
it's runnable
it's doSomething
it's doSomething
it's doSomething
it's doSomething
it's doSomething