wait、notify和notifyAll
首先,这些方法属于Object,而不属于Thread。其次,obj.wait()、obj.notify()必须要与synchronized(obj)一起使用,也就是说obj.wait()、obj.notify()必须存在于synchronized(obj){...}的代码块内(
http://blog.csdn.net/u011796274/article/details/22443535是我上一篇有关于synchronized的博文),负责就会抛出java.lang.IllegalMonitorStateException异常。一下是对这几种方法的简要介绍:
1.如果对象调用了wait方法就会使持有该对象的线程把该对象的控制权交出去,然后处于等待状态(wait()与sleep()及yield()的区别:wait()释放了锁,而后两个没有)。
2.如果对象调用了notify方法就会通知某个正在等待这个对象的控制权的线程可以继续运行。
3.如果对象调用了notifyAll方法就会通知所有等待这个对象控制权的线程继续运行。
注:wait()有3种调用方式:wait()、wait(long timeout)、wait(long timeout)
public class ThreadTest {
public static void main(String[] args) {
final PrintClass pc = new PrintClass();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
pc.ptintText("Thread-1");
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
pc.ptintText("Thread-2");
}
});
t1.start();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.start();
}
}
class PrintClass {
public void ptintText(String text) {
synchronized (this) {
for (int i = 0; i < 15; i++) {
try {
System.out.println(text + ",count" + i);
if("Thread-1".equals(text) && i == 5){
this.wait();
}
if("Thread-2".equals(text) && i == 9){
this.notify();
this.wait();
}
if("Thread-1".equals(text) && i == 14) {
this.notify();
}
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
线程1从0数到5交给线程2,线程2从0数到9再交给线程1,线程1从6数到14再交给线程2,线程2从10数到14,结束。
具体过程是:当线程1数到5时,调用wait()释放了当前的锁,交给了线程2并自己等待。当线程2数到9时,调用notify()激活了某一个等待的线程(这里等待的线程只有线程1,所以只能激活他),并且自己释放了锁,交给另一个线程(只能交给线程1,因为只有他)。然后线程1接着数到14,交给线程2,线程2数完。
在synchronized也可以使用这些方法:
class PrintClass {
public synchronized void ptintText(String text) {
for (int i = 0; i < 15; i++) {
try {
System.out.println(text + ",count" + i);
if("Thread-1".equals(text) && i == 5){
wait();
}
if("Thread-2".equals(text) && i == 9){
notify();
wait();
}
if("Thread-1".equals(text) && i == 14) {
notify();
}
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
将打印类改成这样,与前面的demo效果相同,也是用this这个类实例来同步的。