线程间通信:针对同一个资源的操作有不同种类的线程。 比如有卖票的,也有买票的。
等待唤醒机制:
Object类中提供了3个方法:
wait():等待
notify():唤醒单个线程
notifyAll():唤醒多个线程
这些方法在Object类而不是在Thread类的原因是:方法调用必须通过锁对象调用,而锁对象可以是任意对象。
notify()和notifyAll()的区别
notify()采用顺序操作,依次排序等待
notify()采用非顺序操作,优先级高的有可能先执行
思路
* 生产者:先看是否有数据,有就等待,没有就生产,生产完之后通知消费者 * 消费者:先看是否有数据,有就消费,没有就等待,通知生产者生产数据代码表示
package cn.idcast5;public class SetThread implements Runnable { private Student s; private int x = 0; public SetThread(Student s) { this.s = s; } /* * 思路 * 生产者:先看是否有数据,有就等待,没有就生产,生产完之后通知消费者 * 消费者:先看是否有数据,有就消费,没有就等待,通知生产者生产数据 */ @Override public void run() { while (true) { synchronized (s) { if (s.flag) { // flag默认为false,里面没有数据,所以不用等待 try { s.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if (x % 2 == 0) { s.name = "哈哈哈"; s.age = 10; } else { s.name = "啊啊啊"; s.age = 1; } x++; s.flag = true;// flag变成true,里面有数据了,所以接下来要走等待 s.notify(); } } }}
package cn.idcast5;public class GetThread implements Runnable { private Student s; public GetThread(Student s) { this.s = s; } @Override public void run() { while (true) { synchronized (s) { if (!s.flag) {// 表示有数据,不用等待,直接变成false,然后继续等待 try { s.wait();// t2就等待了,因为里面没有数据 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println(s.name + "---" + s.age); s.flag = false; s.notify(); } } }}