多线程的协作,只会出现在同步过程中。
实现协作的关键字有wait/notify对,join.
1.wait/notify
线程靠对象监视器来同步协作,所以是这样实现的:
- 监视对象obj作为锁,有wait和notify的监视方法。
- 线程使用obj.wait() / obj.notify()来互相通知协作。
wait()可以设置等待时间,不设置的话只有等待通知才会进入运行状态。
notifyAll()
notify()
notify通知了之后,要等当前线程同步语句块执行完,才释放锁给被通知到的线程。如下图,notify对象发出10次通知,最后wait对象也还是得等到notify同步代码执行结束才收到通知。
以上执行结果对应的代码如下:
public class WaitThreadTest extends TestCase {
public void testWait()throws Exception{
Object lock = new Object();
new WaitThread(lock).start();
Thread.sleep(50);
new NotifyThread(lock).start();
Thread.sleep(1000 * 15);
}
}
WaitThread:
synchronized (lock) {
for (int i = 0; i < 10; i++) {
if (MyList.size() < 5) {
System.out.println("才" + MyList.size() + "个,先等待");
// System.out.println("开始 wait time =" + System.currentTimeMillis());
lock.wait();
System.out.println("收到通知");
// System.out.println("结束 wait time = " + System.currentTimeMillis());
}
System.out.println("移除");
MyList.remove();
}
}
NotifyThread:
synchronized (lock){
for (int i = 0 ; i < 10;i++){
MyList.add();
lock.notify();
if (MyList.size() != 5) {
lock.notify();
System.out.println("已经发出了通知");
}
System.out.println("共"+MyList.size()+"个");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
2.join
join其实是给父线程使用自己作为监视对象,调用了自己对象的wait方法。使得父线程等待join的线程执行完毕,才结束。