加载中......
输入验证码,即可复制
微信扫码下载好向圈APP, 登陆后即可进入消息页面查看验证码
只需要3秒时间
在JAVA的Object类中提供了wait和notify方法用于实现线程间通信,源码如下:
/** * 使当前线程等待,直到另外一个线程调用这个对象的notify方法或者是notifyAll方法 * 或者是指定的wait时间过期。 * 当前线程必须拥有该对象的监视器 */ public final native void wait(long timeout) throws InterruptedException;/** * 唤醒一个正在等待该对象的线程监控,如果有任意一个线程在等待这个对象,其中一个线程 * 被选择被唤醒,这个选择是随机的 */ public final native void notify();
wait和notify方法都必须配合synchronized关键字使用,只有进入synchronized方法或者代码块,拿到对象锁之后才能调用该对象锁的wait和notify方法。执行锁对象的wait方法后会释放掉锁,并阻塞住。这样别的线程才有机会获取对象锁,从而才有机会执行synchronized方法/代码块中的锁对象的notify方法。

那么我们通过一个简单的代码实现一个生产/消费者模型:
class ThreadMq {    // 声明一个锁对象    final Object LOCK = new Object();    // 标识生产者是否有数据生产完毕    private volatile boolean isProduced = false;    // 模拟线程间传输的数据    private int i = 0;    /**     * 生产数据的方法     */    public void produce() {        synchronized (LOCK) {            if (isProduced) {                try {                    //当已经有数据生产完毕时,此时线程应当处于阻塞状态,                    //等待消费者把数据消费完成。                    LOCK.wait();                } catch (InterruptedException e) {                    e.printStackTrace();                }            } else {                //当没有数据时(数据被消费完成),此时线程应当消费数据,                //消费完毕时并且通知消费者进行数据消费。                i++;                System.out.println("produce ->" + i);                //唤醒消费者线程                LOCK.notify();                //标识数据已经生产完毕                isProduced = true;            }        }    }    /**     * 消费数据的方法     */    public void consume() {        synchronized (LOCK) {            if (isProduced) {                //当已经有数据生产完毕时,此时消费者消费数据                System.out.println("consume ->" + i);                //数据被消费完毕时,唤醒生产者生产数据                LOCK.notify();                //标识数据已经被消费完毕                isProduced = false;            } else {                try {                    //当没有数据生产完毕时,消费者处于阻塞状态。                    LOCK.wait();                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        }    }}
测试代码如下:
public class ThreadMqTest {    public static void main(String[] args) {        ThreadMq tm = new ThreadMq();        new Thread(()->{            //生产者不断生产数据            while (true){                tm.produce();            }        }).start();        new Thread(()->{            //消费者不断生产数据            while (true){                tm.consume();            }        }).start();    }}produce ->1consume ->1produce ->2consume ->2produce ->3consume ->3produce ->4consume ->4produce ->5consume ->5produce ->6consume ->6produce ->7consume ->7produce ->8consume ->8produce ->9consume ->9produce ->10consume ->10
这种方式在多生产者多消费者的环境中会出现假死锁的情况,意思就是说多个线程都会处于WAITING状态,为了避免这种情况发生,我们可以采用另一种方式。详情见下一篇文章利用notify和wait实现线程间的通讯,实现多生产者和多消费者模型 。
JAVA圈
10593 查看 1 0 反对

说说我的看法高级模式

您需要登录后才可以回帖 登录|立即注册

  • 水泥拌葱

    2021-2-24 14:30:04 使用道具

    来自: 北京来自: 北京来自: 北京来自: 北京
    转发了

相关阅读