转载请标注:
披萨大叔的博客
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();
}
}
}
}
}
}