博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何在 Java 中正确使用 wait, notify 和 notifyAll?
阅读量:6277 次
发布时间:2019-06-22

本文共 3178 字,大约阅读时间需要 10 分钟。

简介

    wait,notify,notifyAll,都是属于object对象提供的方法,但在实际工作中怎么使用这几个方法,确是很多程序员清楚,不够明白,在群里问,有人说,哪个线程想wait,就用

 需等待线程.wait(),就跟Thread.sleep()一样,唤醒也一样,这样显然是不对的。

   在 Java 中可以用 wait、notify 和 notifyAll 来实现线程间的通信。。举个例子,如果你的Java程序中有两个线程——即生产者和消费者,那么生产者可以通知消费者,让消费者开始消耗数据,因为队列缓 冲区中有内容待消费(不为空)。相应的,消费者可以通知生产者可以开始生成更多的数据,因为当它消耗掉某些数据后缓冲区不再为满。

 1、废话不多说,直接看demo吧

package hello.wait_notify;import java.util.LinkedList;import java.util.List;import java.util.Random;import java.util.concurrent.ConcurrentLinkedQueue;/** * Created by jacky on 2017/3/25 0025. */public class Waint_Notify {            public static void main(String args[])        {            ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue();            int maxSize = 10;            Thread producer = new Producer(queue, maxSize, "PRODUCER");            Thread consumer = new Consumer(queue, maxSize, "CONSUMER");            producer.start();            consumer.start();        }   static class Producer extends Thread {        private ConcurrentLinkedQueue queue;        private int maxSize;        public Producer(ConcurrentLinkedQueue queue, int maxSize, String name) {            super(name);            this.queue = queue;            this.maxSize = maxSize;        }        @Override        public void run() {            while (true) {                synchronized (queue) {                    while (queue.size() == maxSize) {                        try {                            System.out.println("队列中已经满了,等待消费者消费!");                            queue.wait();                        } catch (Exception ex) {                            ex.printStackTrace();                        }                    }                    Random random = new Random();                    int i = random.nextInt();                    System.out.println("Producing value : " + i);                    queue.add(i);                    queue.notifyAll();                }            }        }    }   static class Consumer extends Thread {        private ConcurrentLinkedQueue queue;        private int maxSize;        public Consumer(ConcurrentLinkedQueue queue, int maxSize, String name) {            super(name);            this.queue = queue;            this.maxSize = maxSize;        }        @Override        public void run() {            while (true) {                synchronized (queue) {                    while (queue.isEmpty()) {                        System.out.println("队列已经空了,等待生产者放数据" );                        try {                            queue.wait();                        } catch (Exception ex) {                            ex.printStackTrace();                        }                    }                    System.out.println("Consuming value : " + queue.remove());                    queue.notifyAll();                }            }        }    }}

2、结果

3、总结

1. 你可以使用wait和notify函数来实现线程间通信。你可以用它们来实现多线程(>3)之间的通信。

2. 永远在synchronized的函数里使用wait、notify和notifyAll,不然Java虚拟机会生成 IllegalMonitorStateException。

3. 永远在while循环里而不是if语句下使用wait。这样,循环会在线程睡眠前后都检查wait的条件,并在条件实际上并未改变的情况下处理唤醒通知。

4. 永远在多线程间共享的对象(在生产者消费者模型里即缓冲区队列)上使用wait。

5. 基于前文提及的理由,更倾向用 notifyAll(),而不是 notify()。

转载于:https://www.cnblogs.com/520playboy/p/6616493.html

你可能感兴趣的文章
InnoDB引擎的索引和存储结构
查看>>
Selenium私房菜系列8 -- 玩转Selenium Server
查看>>
重学自动控制 PID
查看>>
游戏演示(包含源码)[名称待定]
查看>>
浅析SQL Server实现分布式事务的两阶段提交协议2PC
查看>>
IBM WebSphere 产品介绍
查看>>
结构型模式之Adapter模式
查看>>
仅用18天,英伟达新型GAN合成真假难辨高清明星脸
查看>>
C# 泛型编程之泛型类、泛型方法、泛型约束
查看>>
MAT文件操作
查看>>
【英语天天读】Heart of a stranger 陌生的心灵
查看>>
wp7 Emulator模拟器停止工作原因
查看>>
iBATIS.net直接执行sql语句
查看>>
Matlab Command Window 进度提示
查看>>
Windows on Device 项目实践 3 - 火焰报警器制作
查看>>
数据库备份与还原SQL代码
查看>>
http的请求和响应过程1
查看>>
ASP.NET Core: 全新的ASP.NET !
查看>>
64位下的Visual Studio的编辑并继续
查看>>
beanstalkd 消息队列的第一手资料
查看>>