Java基础学习——多线程(线程间通信-生产者消费者代码示例)
JDK 1.5提供了多线程升级方案
将同步synchronized替换成了显示的Lock操作。可以实现唤醒、冻结指定的线程。
Lock接口
Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作。此实现允许更灵活的结构,可以具有差别很大的属性,可以支持多个相关的 Condition 对象。
线程间通信Condition接口
Condition可以替代传统的线程间通信,用await()替换wait(),用signal()替换notify(),用signalAll()替换notifyAll()。该对象可以通过Lock锁进行获取。
传统线程的通信方式,Condition都可以实现。
注意,Condition是被绑定到Lock上的,要创建一个Lock的Condition必须用newCondition()方法。
ReentrantLock类
Java.util.concurrent.lock 中的Lock 框架是锁定的一个抽象,它允许把锁定的实现作为 Java 类,而不是作为语言的特性来实现。这就为Lock 的多种实现留下了空间,各种实现可能有不同的调度算法、性能特性或者锁定语义。
ReentrantLock 类实现了Lock ,它拥有与synchronized 相同的并发性和内存语义,但是添加了类似锁投票、定时锁等候和可中断锁等候的一些特性。此外,它还提供了在激烈争用情况下更佳的性能。(换句话说,当许多线程都想访问共享资源时,JVM 可以花更少的时候来调度线程,把更多时间用在执行线程上。)
用法示例:
private Lock lock = new ReentrantLock();//定义多态ReentrantLock类对象
private Condition cond_pro = lock.newCondition();//Condition是被绑定到Lock上的,要创建一个Lock的Condition必须用Lock对象的newCondition()方法。
private Condition cond_con = lock.newCondition();//一个lock可以有多个相关的condition
首先创建一个ReentrantLock类的多态对象,即建立一把锁。然后将这把锁与两个Condition对象关联。
实例:
import java.util.concurrent.locks.*;class ProducerConsumerDemo {public static void main(String[] args) {Resource r = new Resource();Producer pro = new Producer(r);//生产者对象Consumer con = new Consumer(r);//消费者对象Thread t1 = new Thread(pro);Thread t2 = new Thread(pro);Thread t3 = new Thread(con);Thread t4 = new Thread(con);t1.start();t2.start();t3.start(); t4.start(); }}class Resource{private String name;private int count = 1;private boolean flag = false;private Lock lock = new ReentrantLock();//定义一个实现Lock接口的ReentrantLock类对象private Condition cond_pro = lock.newCondition();//Condition是被绑定到Lock上的,要创建一个Lock的Condition必须用Lock对象的newCondition()方法。private Condition cond_con = lock.newCondition();//一个lock可以有多个相关的conditionpublic void set(String name) throws InterruptedException//生产方法//注意这里抛出await()方法异常声明,交给调用者处理{lock.lock(); //手动加同步锁try{ while (flag) //if→while 此时若生产完一个以后唤醒了另一个生产者,则再次判断,避免了两个生产者同时生产cond_pro.await(); //冻结生产方法this.name = name+"____"+count++;System.out.println(Thread.currentThread().getName()+"_______"+"生产者"+this.name);flag = true;cond_con.signal(); //唤醒消费方法,利用了condition的signal()指定唤醒对象 }finally //{lock.unlock();}}public void out()throws InterruptedException{lock.lock();try{while (!flag)cond_con.await();System.out.println(Thread.currentThread().getName()+"______"+"消费者"+this.name);flag = false;cond_pro.signal();}finally //释放锁必须得到执行{lock.unlock();}}}class Consumer implements Runnable{private Resource res;public Consumer(Resource res){this.res = res;}public void run(){while (true){try //由于out()方法抛出了异常声明,这里必须捕获。{res.out();}catch (InterruptedException e){}}}}class Producer implements Runnable{private Resource res;public Producer(Resource res){this.res = res; }public void run(){while (true){ try{res.set("+商品+");}catch (InterruptedException e){}}}}
执行上述代码,观察结果:
可以看到,多个线程同时生产、消费,由于指定唤醒互异线程,因此并不会引起错误。
Java基础学习——多线程(线程间通信-生产者消费者代码示例)相关推荐
- java 生产者消费者_Java多线程:线程间通信—生产者消费者模型
一.背景 && 定义 多线程环境下,只要有并发问题,就要保证数据的安全性,一般指的是通过 synchronized 来进行同步. 另一个问题是, 多个线程之间如何协作呢 ? 我们看一个 ...
- 多线程-线程间通信-多生产者多消费者示例
1.多线程-线程间通信-多生产者多消费者问题 多生产者和多消费者.等待唤醒机制. 产生了两个问题: 1.出现了多次连续生产,未消费,或者一个商品被消费多次. 解决:必须要--------每一个被唤醒的 ...
- java基础学习-多线程笔记
说说Java中实现多线程有几种方法 创建线程的常用三种方式: 1. 继承Thread类 2. 实现Runnable接口 3. 实现Callable接口( JDK1.5>= ) 4. 线程池方式创 ...
- java synoch 加锁_线程间通信 - HappyCowboy - 博客园
线程之间需要一些协调通信,来共同完成一件任务.Java多线程中,线程之间通信最常用的两个方法是wait()与notify() 使用wait()与notify()实现线程间的通信,需注意: ①wait( ...
- 抖音最后一面,问我Java 是如何实现线程间通信的?
线程之间到底使用什么沟通的呢?如何把数值变化传递给其他子线程? 来源:blog.csdn.net/lanxian837820149/article/details/101479004 MarkerHu ...
- 【转】Java里如何实现线程间通信
正常情况下,每个子线程完成各自的任务就可以结束了.不过有的时候,我们希望多个线程协同工作来完成某个任务,这时就涉及到了线程间通信了. 本文涉及到的知识点:thread.join(), object.w ...
- Java基础21 多线程线程两种实现方式 锁
一.多线程的概念 1.程序 :一个固定逻辑与数据的集合 就称为程序 例如淘宝 贪吃蛇小游戏 2.CPU: 中央处理器 主要用于协调程序与硬件进行配置的工作 3.并发与并行 1.并发(高并发) 在同一个 ...
- linux高级编程基础系列:线程间通信
线程间通信机制: 线程是一种轻量级的进程. 进程的通信机制主要包括无名管道.有名管道.消息队列.信号量.共享内存以及信号等.这些机制都是由linux内核来维护的,实现起来都比较复杂,而且占用大量的系统 ...
- java Thread学习(线程间协作)
线程件协作 线程之间除了使用锁同步两个任务的行为外,还需要进行协作,例如任务A必须在B完成后才能执行. wait()和notify()/notifyAll() wait()会去等待外部信号,并且在等待 ...
最新文章
- debian下编译安装php5.2
- suse 启动oracle11g,SuSe10下Oracle11g文件系统模式安装及配置、网络配置与连接
- python3.5文档
- java.lang.NoClassDefFoundError: org/apache/commons/collections/map/LRUMap 解决方法
- 自动挡跑高速用S挡还是D挡? 回答
- bzoj 4131: 并行博弈(博弈)
- linux根目录9个g,linux根目录下5个主要的目录,及目录的功能
- HashMap的实现原理、JDK1.7和JDK1.8的对比以及死锁问题
- 关于公众号文章搜索,有两个小技巧
- VS2012使用 MSDN教程
- lisp成套电气设计_关于成套设计转电气设计问题?
- 网页唤起QQ临时会话
- Android 性能优化 (十一) 电量优化全解析 秒变大神
- 单片机超声波测距模块原理与源码解析
- MyBatisPuls入门案例
- 在单机上通过docker搭建redis集群试验
- 2022秋招前端面试题(一)(附答案)
- 【LeetCode】不含重复字符的最长子字符串
- Dell戴尔笔记本电脑G3 3579原装出厂Windows10系统恢复原厂oem系统
- 三极管的检测及其管脚的判别