Java synchronized似乎被忽略了

时间:2010-03-23 12:38:43

标签: java multithreading synchronization deadlock

我有以下代码,我打算在打印出“Main:pre-sync”之后死锁。但看起来synchronized并没有达到我的预期。这里发生了什么?

import java.util.*;

public class deadtest {
   public static class waiter implements Runnable {
      Object obj;

      public waiter(Object obj) {
         this.obj = obj;
      }

      public void run() {
         System.err.println("Thead: pre-sync");
         synchronized(obj) {
            System.err.println("Thead: pre-wait");
            try {
               obj.wait();
            } catch (Exception e) {
            }
            System.err.println("Thead: post-wait");
         }
         System.err.println("Thead: post-sync");
      }
   }

   public static void main(String args[]) {
      Object obj = new Object();

      System.err.println("Main: pre-spawn");

      Thread waiterThread = new Thread(new waiter(obj));
      waiterThread.start();

      try {
         Thread.sleep(1000);
      } catch (Exception e) {
      }  

      System.err.println("Main: pre-sync");
      synchronized(obj) {
         System.err.println("Main: pre-notify");
         obj.notify();
         System.err.println("Main: post-notify");
      }
      System.err.println("Main: post-sync");

      try {
         waiterThread.join();
      } catch (Exception e) {
      }
   }
}

由于两个线程在创建的对象上同步,我希望线程实际上相互阻塞。目前,代码很高兴地通知其他线程,加入和退出。

2 个答案:

答案 0 :(得分:4)

当你在一个对象上wait()时,该线程释放对象上的锁,以允许其他人获取锁和notify()等待线程。请参阅javadoc for Object.wait()

  

当前线程必须拥有此对象的监视器。 线程释放此监视器的所有权并等待,直到另一个线程通过调用notify方法或notifyAll方法通知等待此对象监视器的线程唤醒。 线程然后等待,直到它可以重新获得监视器的所有权并继续执行

答案 1 :(得分:4)

在监视器上调用.wait()实际上会释放同步锁,以便其他线程可以锁定到同一监视器并发送通知。

您的行为完全正常:“服务员”锁定监视器,然后在等待通知时释放锁定。 1秒钟后,主线程锁定监视器,发送通知,解锁监视器,唤醒服务员完成其操作。