多线程下的生产者消费者(一个初始值为0的变量,两个线程一个加1一个减1,轮询5轮)
在使用Lock之前,我们使用的最多的同步方式应该是synchronized关键字来实现同步方式了。配合Object的wait()、notify()系列方法可以实现等待/通知模式。Condition接口也提供了类似Object的监视器方法,与Lock配合可以实现等待/通知模式
下面用的是lock锁
首先我们需要明白condition对象是依赖于lock对象的,condition对象需要通过lock对象进行创建出来(调用Lock对象的newCondition()方法)。condition的使用需要在调用方法前获取锁。
1.传统版
- 题目:一个初始值为0的变量,两个线程一个加1一个减1,轮询5轮
- 线程 操作(方法) 资源类
- 判断 干活 通知
- 防止虚假唤醒机制(多线程判断用while不用if)
package JUC;import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;class ShareData {private int number = 0;Lock lock = new ReentrantLock();private Condition condition = lock.newCondition();public void increment() throws InterruptedException {lock.lock();try {//1.判断while (number != 0) {//线程判断用while//等待不能生产condition.await();}//2.干活number++;System.out.println(Thread.currentThread().getName() + "\t" + number);//3.通知唤醒condition.signalAll();} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}public void decrement() throws InterruptedException {lock.lock();try {//1.判断while (number == 0) {//线程判断用while//等待不能生产condition.await();}//2.干活number--;System.out.println(Thread.currentThread().getName() + "\t" + number);//3.通知唤醒condition.signalAll();} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}
}/*** 题目:一个初始值为0的变量,两个线程一个加1一个减1,轮询5轮* <p>* 1. 线程 操作(方法) 资源类* 2. 判断 干活 通知* 3.防止虚假唤醒机制(多线程判断用while不用if)*/
public class ProdConsumer_TraditonDemo {public static void main(String[] args) {ShareData shareData = new ShareData();new Thread(() -> {for (int j = 0; j < 5; j++) {try {shareData.increment();} catch (InterruptedException e) {e.printStackTrace();}}}, "AA").start();new Thread(() -> {for (int j = 0; j < 5; j++) {try {shareData.decrement();} catch (InterruptedException e) {e.printStackTrace();}}}, "BB").start();}
}
2.Condition精准唤醒( condition.signal() )
/**
- 题目:多线程之间按顺序调用,实现A->B->C三个线程启动,需求如下:
- AA打印5次,BB打印10次,CC打印15次
- 紧接着
- AA打印5次,BB打印10次,CC打印15次
- 。。。
- 。。。
- 。。。
- 来10轮
*/
package JUC;import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;/*** 题目:多线程之间按顺序调用,实现A->B->C三个线程启动,需求如下:* AA打印5次,BB打印10次,CC打印15次* 紧接着* AA打印5次,BB打印10次,CC打印15次* 。。。* 。。。* 。。。* 来10轮*/class ShareResource{//资源类private int number = 1; //AA就是1,BB就是2,CC就是3private Lock lock = new ReentrantLock();private Condition c1 = lock.newCondition();private Condition c2 = lock.newCondition();private Condition c3 = lock.newCondition();//1.判断public void print5(){lock.lock();try {//1.判断while(number!=1){c1.await();}//2.干活for (int i = 1; i <= 5; i++) {System.out.println(Thread.currentThread().getName() + "\t" + i);}//3.通知number = 2;c2.signal();}catch (Exception e){e.printStackTrace();}finally {lock.unlock();}}public void print10(){lock.lock();try {//1.判断while(number!=2){c2.await();}//2.干活for (int i = 1; i <= 10; i++) {System.out.println(Thread.currentThread().getName() + "\t" + i);}//3.通知number = 3;c3.signal();}catch (Exception e){e.printStackTrace();}finally {lock.unlock();}}public void print15(){lock.lock();try {//1.判断while(number!=3){c3.await();}//2.干活for (int i = 1; i <= 15; i++) {System.out.println(Thread.currentThread().getName() + "\t" + i);}//3.通知number = 1;c1.signal();}catch (Exception e){e.printStackTrace();}finally {lock.unlock();}}}
public class SyncAndReentrantLockDemo {public static void main(String []args){ShareResource shareResource = new ShareResource();new Thread(()->{for (int i = 1; i < 10; i++) {shareResource.print5();}},"AA").start();new Thread(()->{for (int i = 1; i < 10; i++) {shareResource.print10();}},"BB").start();new Thread(()->{for (int i = 1; i < 10; i++) {shareResource.print15();}},"CC").start();}
}
结果:只截取了一轮
AA 1
AA 2
AA 3
AA 4
AA 5
BB 1
BB 2
BB 3
BB 4
BB 5
BB 6
BB 7
BB 8
BB 9
BB 10
CC 1
CC 2
CC 3
CC 4
CC 5
CC 6
CC 7
CC 8
CC 9
CC 10
CC 11
CC 12
CC 13
CC 14
CC 15
多线程下的生产者消费者(一个初始值为0的变量,两个线程一个加1一个减1,轮询5轮)相关推荐
- 高并发编程-使用wait和notifyAll进行线程间的通信3_多线程下的生产者消费者模型和notifyAll
文章目录 概述 解决办法 概述 高并发编程-线程通信_使用wait和notify进行线程间的通信2_多生产者多消费者导致程序假死原因分析 中分析了假死的原因,这里我们来看下改如何解决在多线程下出现的这 ...
- 单线程下的生产者--消费者模式详解,wait和sleep的区别
1. 单线程下的生产者--消费者模式 1.1 该模式下,一个线程生产数据,另一个线程处理数据.当数据还没被处理,那么生产数据的线程进入等待状态:如果数据还没生产,那么处理数据的线程进入等待状态,代码及 ...
- 递归实现牛顿法求整数平方根(原理: 给一个初始值(比如X1 = a/2)迭代求a的平方根,设定一个误差限,不断逼近a X1 = a/2 X2 = (X1+a/X1)/
题目: /* 递归实现牛顿法求整数平方根(原理: 给一个初始值(比如X1 = a/2)迭代求a的平方根,设定一个误差限,不断逼近a X1 = a/2 X2 = (X1+a/X1)/2 - - - Xn ...
- C#会对于未赋值的变量/成员变量,给予一个初始值吗?
如果我有程序如下: C# code ? 1 2 3 4 5 6 7 public class My { public bool b; public in ...
- 树莓派 | threading01 - 创建两个子线程同时运行,两个线程各负责控制一个LED灯以不同的频率闪烁
文章目录 一.前言 二.代码 三.运行 一.前言 Python | threading01 - 创建两个同时运行的子线程 上一次使用了python的多线程库threading创建了两个同时运行的子线程 ...
- Java多线程(含生产者消费者模式详解)
多线程 导航 多线程 1 线程.进程.多线程概述 2 创建线程 (重点) 2.1 继承Thread类(Thread类也实现了Runnable接口) 2.2 实现Runnable接口(无消息返回) 2. ...
- java多线程抽奖_java 线程池、多线程并发实战(生产者消费者模型 1 vs 10) 附案例源码...
导读 前二天写了一篇<Java 多线程并发编程>点我直达,放国庆,在家闲着没事,继续写剩下的东西,开干! 线程池 为什么要使用线程池 例如web服务器.数据库服务器.文件服务器或邮件服务器 ...
- python多线程问题及生产者消费者示例
多线程能干什么: 生产者消费者问题: 一直生产,一直消费,中间有阀值,避免供求关系不平衡,导致出现问题. #线程安全问题,要是线程同时来,听谁的 #锁:一种数据结构 队列:先进线出 栈:先进后出1.解 ...
- mysql服务器多线程模型_java 线程池、多线程并发实战(生产者消费者模型 1 vs 10) 附案例源码 - 陈彦斌 - 博客园...
导读 前二天写了一篇<Java 多线程并发编程>点我直达,放国庆,在家闲着没事,继续写剩下的东西,开干! 线程池 为什么要使用线程池 例如web服务器.数据库服务器.文件服务器或邮件服务器 ...
最新文章
- ruby网站部署到服务器,入门知识: 把代码部署到服务器, SSH
- 日均请求量百亿级数据处理平台的容器云实践
- Keil uVision5 之 C51 与 MDK 共存
- selenium基础框架的封装(Python版)这篇帖子在百度关键词搜索的第一位了,有图为证,开心!...
- C语言题目地图上有m个城市,序号依次为1,2,3....m,刚开始你在1,若每次只能从当前城市去往当前序号加1或者加3的城市,要到达m城市(m3),有多少种走法
- ubuntu安装常用软件(比如python、搜狗拼音、cudnn等)
- Php 安装 zend_loader,在Linux系统中为PHP5.x安装Zend Guard Loader
- python bool类型如何与整数比较_Python入门必读bool类型和比较运算符
- 在矩池云上复现 PaddleGAN 照片转油画风格教程
- pandas多行合并一行_Pandas函数妙用
- python123平台在线编程_Python程序设计实验报告一:熟悉IDLE和在线编程平台
- [Java] Lambda表达式
- 三维地质建模数据处理
- 学生信息管理系统(头哥适用版)(c语言)
- 宝塔php memory_limit,优化宝塔面板提高网站运行速度教程
- autogen.sh出错
- Intel IPP 之图像压缩编码
- 影像匹配代码,论文:Remote sensing image matching featured by the optimal entropy classification
- 海信电视微助手怎么连接电脑连接网络连接服务器,海信智能电视连接手机的教程详解!...
- 计算机任务计划命令,从菜鸟到高手,CMD命令行计划任务设置(上):at
热门文章
- Centos7 Apache 2.4.18编译安装
- EJB通过ANT提高EJB应用程序的开发效率、无状态发展本地接口bean、开发状态bean...
- pytorch中的squeeze和unsqueeze
- [Leedcode][JAVA][第542题][01矩阵][BFS]
- python 元组遍历_Python中的for循环:元组、列表、字典的遍历和相互转化
- 使用 IPsec 与组策略隔离服务器和域-第 7 章 IPsec 疑难解答
- IDEA快捷键的使用成就手速之旅(要想手速变得快,快捷练习必须刚)
- tx2无法识别网络_Jetson TX2开篇--网络配置
- 哲学家就餐问题python_Python实现哲学家就餐问题实例代码
- c语言链表编程作业,C语言编程入门——链表