有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java调用同步方法的顺序

我相信,这是一个简单的问题,但我还是不明白。我有以下代码

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()在线程之前?此外,如果我在synchro block之后调用多个object方法,它们都会被后续调用,只有这样程序才会返回到线程的内容。如果我将synchro块中的线程调用行替换为,比如,调用某个模拟对象方法,那么一切都可以,并且按照指定的顺序进行

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


共 (2) 个答案

  1. # 1 楼答案

    这里有一个竞态条件:你的runnable在启动时会在等待监视器时被阻塞,原因是它的创建周围有synchronized (object)。一旦创建runnable的线程释放了监视器,新创建的具有runnable的线程就没有机会抓住它,因为同一线程在doSomething()方法中再次进入它

    如果在调用object.doSomething()之前添加对Thread.sleep(100);的调用

    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
    
  2. # 2 楼答案

    因为主线程是第一个获得锁的线程。它可能是生成的线程,您只是不能确定,尽管可能性要小得多,因为调用start()之后,线程需要一段时间才能真正开始运行

    关于你剩下的问题,答案太模糊了