wait(), notify(),sleep()详解

来源:互联网 发布:js上传图片本地预览 编辑:程序博客网 时间:2024/05/16 23:34

转载请标注:
披萨大叔的博客
http://blog.csdn.net/qq_27258799/article/details/51859450

首先说说sleep()和wait()的区别

1、wait()是Object方法,sleep()是Thread方法。

2、锁是Object对象内的机制,所以我们可以简单记忆为,sleep()不会改变锁行为,因此wait()会释放对象锁,sleep()不会。

3、wait()、notify()、notifyAll()只能用在同步控制块或同步控制方法里,即,他们要和synchronized搭配使用,而sleep()可以在任何地方使用。

4、sleep()必须捕获异常、而wait()、notify()、notifyAll()不强制捕获。

5、Thread.sleep()和Object.wait()都会暂停当前的线程,对于CPU资源来说,不管是哪种方式暂停的线程,都表示它暂时不再需要CPU的执行时间。OS会将执行时间分配给其它线程。区别是,调用wait后,需要别的线程执行notify/notifyAll才能够重新获得CPU执行时间。

wait()和notify()

wait()会释放对象锁,同时本线程休眠,等待被唤醒,notify()就是唤醒操作。值得一提的是,notify()并不会立刻释放当前锁,而是在自己的synchronized块执行完毕,释放了自己的锁后,由JVM在wait()对象锁的线程中随机选取一个线程,赋予对象锁,并唤醒线程。

三线程打印

关于wait()和notify()的使用,有一道经典算法面试题:要求3个线程依次打印ABC,并且循环10次。

public class TestAsynTread {      public static void main(String argv[]) {          AtomicInteger synObj = new AtomicInteger(0);          TestPrint a = new TestPrint(synObj, "A", 0);          TestPrint b = new TestPrint(synObj, "B", 1);          TestPrint c = new TestPrint(synObj, "C", 2);          a.start();          b.start();          c.start();      }  }  class TestPrint extends Thread {      private AtomicInteger synObj;      private String name;      private int flag;      private int count = 0;      public TestPrint(AtomicInteger synObj, String name, int flag) {          this.synObj = synObj;          this.name = name;          this.flag = flag;      }      @Override      public void run() {          while (true) {              synchronized (synObj) {                  if (synObj.get() % 3 == flag) {                      synObj.set(synObj.get() + 1);                      System.out.println(name);                      count++;                      synObj.notifyAll();                      if (count == 10) {                          break;                      }                  } else {                      try {                          synObj.wait();                      } catch (InterruptedException e) {                         e.printStackTrace();                      }                  }              }          }      }  }  
1 0