Java多线程知识点总结——进阶篇(七) 之 等待唤醒机制
2018-03-31 15:47
645 查看
1、线程的通信方式通信:
其实就是多个线程在操作同一个资源,但是操作的动作不同。
2、API介绍
Object.wait():在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。
Object.notify():唤醒在此对象监视器上等待的单个线程。
Object.notifyAll():唤醒在此对象监视器上等待的所有线程。
先来实现一个需求:
有两个线程,一个往资源池中生产数据,一个从资源池中消费数据
代码如下:
上面再生产和消费都是单线程的情况下是没有问题的,但是如果变成了两个生产者和两个消费者,且该资源池只能存放一条数据,那么上面代码就需要修改了。
第一点:需要将上面代码的 notify() 改成 notifyAll()。因为只用notify,容易出现只唤醒本方线程的情况。导致程序中的所有线程都等待。
第二点:需要将
改成:
原因:让被唤醒的线程再一次判断标记。
多线程版本的完整代码如下:
其实就是多个线程在操作同一个资源,但是操作的动作不同。
2、API介绍
Object.wait():在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。
Object.notify():唤醒在此对象监视器上等待的单个线程。
Object.notifyAll():唤醒在此对象监视器上等待的所有线程。
先来实现一个需求:
有两个线程,一个往资源池中生产数据,一个从资源池中消费数据
代码如下:
class Res { private String name; private String sex; private boolean flag = false; //用来判断有没有数据 /** * 生产一条数据 * @param name * @param sex */ public synchronized void set(String name, String sex) { if (flag) try {this.wait();} catch (Exception e) {} this.name = name; this.sex = sex; flag = true; this.notify(); //唤醒另一个线程 } /** * 消费数据 */ public synchronized void out() { if (!flag) try {this.wait();} catch (Exception e) {} System.out.println(name + "........" + sex); flag = false; this.notify(); } } class Input implements Runnable { private Res r; Input(Res r) { this.r = r; } public void run() { int x = 0; while (true) { 4000 if (x == 0) r.set("mike", "man"); else r.set("丽丽", "女女女女女"); x = (x + 1) % 2; } } } class Output implements Runnable { private Res r; Output(Res r) { this.r = r; } public void run() { while (true) { r.out(); } } } class InputOutputDemo2 { public static void main(String[] args) { Res r = new Res(); new Thread(new Input(r)).start(); new Thread(new Output(r)).start(); } }
上面再生产和消费都是单线程的情况下是没有问题的,但是如果变成了两个生产者和两个消费者,且该资源池只能存放一条数据,那么上面代码就需要修改了。
第一点:需要将上面代码的 notify() 改成 notifyAll()。因为只用notify,容易出现只唤醒本方线程的情况。导致程序中的所有线程都等待。
第二点:需要将
if (flag) try {this.wait();} catch (Exception e) {}
改成:
while(flag) try {this.wait();} catch (Exception e) {}
原因:让被唤醒的线程再一次判断标记。
多线程版本的完整代码如下:
class ProducerConsumerDemo { public static void main(String[] args) { Resource r = new Resource(); Producer pro = new Producer(r); Consumer con = new Consumer(r); new Thread(pro).start(); new Thread(pro).start(); new Thread(con).start(); new Thread(con).start(); } } class Resource { private String name; private int count = 1; private boolean flag = false; // t1 t2 public synchronized void set(String name) { while (flag) try {this.wait();} catch (Exception e) {}// t1(放弃资格) t2(获取资格) this.name = name + "--" + count++; System.out.println(Thread.currentThread().getName() + "...生产者.." + this.name); flag = true; this.notifyAll(); } // t3 t4 public synchronized void out() { while (!flag) try {wait();} catch (Exception e) {}// t3(放弃资格) t4(放弃资格) System.out.println(Thread.currentThread().getName() + "...消费者........." + this.name); flag = false; this.notifyAll(); } } class Producer implements Runnable { private Resource res; Producer(Resource res) { this.res = res; } public void run() { while (true) { res.set("+商品+"); } } } class Consumer implements Runnable { private Resource res; Consumer(Resource res) { this.res = res; } public void run() { while (true) { res.out(); } } }
相关文章推荐
- Java多线程知识点总结——进阶篇(八) 之 等待唤醒机制 Lock 锁升级版
- java多线程中的生产者与消费者之等待唤醒机制@Version2.0
- Java多线程四:线程间通信/等待唤醒机制
- 黑马程序员——Java基础——多线程的同步、死锁和等待唤醒机制
- java多线程(2):线程通信之生产者消费者模式及等待唤醒机制
- java 中多线程之间的通讯之等待唤醒机制
- 黑马程序员_java的多线程进阶(对第十二课等待唤醒机制和生产消费总结)
- Java多线程知识点总结——进阶篇(四)之静态同步函数用的是哪一个锁问题
- Java多线程知识点总结——进阶篇(五)之多线程下的单例模式
- java多线程之 生产者和消费者 线程间通信 等待与唤醒机制
- JAVA进阶知识点总结(3)— 多线程
- 【我的Java笔记】多线程_等待唤醒机制(生产消费者模式)
- 黑马程序员——java多线程之死锁和等待唤醒机制
- java 多线程等待与唤醒机制
- Java多线程之线程通信生产者消费者模式及等待唤醒机制代码详解
- Java---18---多线程:等待唤醒机制
- java多线程等待唤醒机制
- java 多线程-————等待唤醒机制
- JAVA之旅(十四)——静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制
- java多线程中的生产者与消费者之等待唤醒机制@Version1.0