多线程下的生产者消费者(一个初始值为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轮
    1. 线程 操作(方法) 资源类
    1. 判断 干活 通知
    1. 防止虚假唤醒机制(多线程判断用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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/437569.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

synchronized和ReentrantLock区别,用新的lock有什么好处?举例说说

原始构成&#xff1a;synchronized是JVM层面的&#xff0c;底层通过monitorenter和monitorexit来实现的。Lock是JDK API层面的。&#xff08;synchronized一个enter会有两个exit&#xff0c;一个是正常退出&#xff0c;一个是异常退出&#xff08;保证肯定可以退出&#xff09;…

阻塞队列,来写生产者消费者,生产一个消费一个

用阻塞队列来写&#xff0c;就不需要程序员来关心什么时候阻塞线程await&#xff0c;什么时候唤醒线程notify&#xff08;&#xff09;。 类似消息中间件 package JUC;import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import…

Callable接口-创建线程的第三种方法

Callable和Runable相比 //Runnable和Callable区别 //1.Callable带返回值 //2.run()不会抛异常&#xff0c;call()会抛异常 //3.实现的接口不同 package JUC;import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concur…

线程池ThreadPool,线程池底层ThreadPoolExecutor方法七大参数,拒绝策略,以及实际开发中高并发下用到哪个线程池?

为什么要用线程池 基本的三个线程池的底层就是ThreadPoolExecutor类 ExecutorService threadPool Executors.newFixedThreadPool(int);//固定线程数的线程池&#xff0c;&#xff0c;执行长期的任务&#xff0c;性能好 ExecutorService threadPool Executors.newSingleThrea…

【转】2.1.1 购买阿里云服务器(Ubuntu系统)

购买阿里云服务器 优惠购买链接 戳我购买 Cpu和内存 M2对服务器配置要求比较高&#xff0c; cpu要大于等于1, 内存要大于等于2 选择Ubuntu镜像 最好用官方提供的公共镜像&#xff0c;不要用第三方的。 其他的配置 其他的配置按你自己的需求来选择。 控制台 购买完成后…

死锁编码及定位分析(故障排查)

什么是死锁&#xff1f; 在Java中使用多线程&#xff0c;就会有可能导致死锁问题。死锁会让程序一直卡住&#xff0c;不再程序往下执行。我们只能通过中止并重启的方式来让程序重新执行。 造成死锁的原因&#xff1a; 当前线程拥有其他线程需要的资源当前线程等待其他线程已…

【转】在win10接双显示器(扩展模式)怎么把鼠标游标切换到第二台显示器上?

作者&#xff1a;朱宁 链接&#xff1a;https://www.zhihu.com/question/50002939/answer/120465673 来源&#xff1a;知乎 著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。 使用软件 DisplayFusion Pro 这个软件体量比较大&#xff0c;蓝…

JAVA的Future类

学习callable中用到了Future&#xff0c;找了个博客&#xff0c;可以看下 https://blog.csdn.net/u014209205/article/details/80598209

java单例模式(饿汉式和懒汉式的几种不同写法)

1.饿汉式&#xff08;直接创建&#xff09;三种创建方法代码里面都有 第三种静态代码块方式&#xff0c;需要创建个properties文件 package java2;import java.io.IOException; import java.util.Properties;/*** 单例模式设计步骤&#xff1a;* 1.构造器私有化* 2.内部创…

【转】一键将Web应用发布到云-Azure Web App!

我们现在越来越多的传统应用&#xff0c;逐步向云端迁移&#xff0c;原先私有云的部署模式&#xff0c;逐步向云端PaaS IaaS转变。例如&#xff1a; 我们在云端Azure中申请VM虚拟机&#xff0c;将我们的Web应用部署到VM的IIS中&#xff0c;同时做云服务的高可用性集和NLB&…

【转】微软Azure Functions使用入门

微软公司于近期发布了Azure Functions以支持AWS Lambda。本文将介绍如何开始使用这个事件驱动服务&#xff0c;以及这项服务是否适合您。 无论是超大规模云供应商、软件开放人员还是企业管理员&#xff0c;目前最热门的技术之一就是无服务器计算。也就是所谓的功能即服务&…

【转】The underlying connection was closed

转自: https://support.microsoft.com/en-us/kb/915599 SUMMARY This article describes error messages that you may receive when you use the Microsoft .NET Framework 1.1 Service Pack 1 (SP1) to make HTTP requests or when you call a Web service. SYMPTOMS Whe…

jvm详解、GC、堆内存参数调优

一些常见面试题&#xff1a; JVM的位置&#xff08;运行在操作系统上&#xff0c;与硬件没有直接的交互&#xff09; 一、jvm体系结构&#xff08;记住背下来&#xff09; 运行时数据区&#xff1a;有亮色的有灰色的&#xff0c;灰色的就是占得内存非常小&#xff0c;几乎不存…

【转】!Dynamics 365 Online通过OAuth 2 Client Credential授权(Server-to-Server Authentication)后调用Web API

微软动态CRM专家罗勇 &#xff0c;回复332或者20190505可方便获取本文&#xff0c;同时可以在第一间得到我发布的最新博文信息&#xff0c;follow me&#xff01; 本文很多内容来自 John Towgood 撰写的Dynamics 365 Online Authenticate with Client Credentials &#xff0c…

JMM(java内存模型)

这篇文章写得挺好的&#xff1a;https://blog.csdn.net/javazejian/article/details/72772461 在多线程环境下&#xff0c;线程之间的要通信,就不得不提JMM(java内存模型) 在JVM内部使用的java内存模型(JMM)将线程堆栈和堆之间的内存分开 jmm的承诺&#xff1a; 1.原子性 2.可…

【转】Postman 生成接口文档

引言 几个朋友想做一个前后端分离的项目&#xff0c;接口文档的重要性那是不言而喻的。生成接口文档的方法真的太多了&#xff0c;Yapi、Swagger等等。但是想公网上访问接口文档并修改的话&#xff0c;还得购买服务器&#xff0c;部署上去。穷码农&#xff0c;哪有钱购买服务器…

JVM的进阶学习(GC Roots、JVM调优与参数配置、)

1. GC Roots&#xff0c;可达性分析 从GC roots的对象作为起始点&#xff0c;从GC Roots对象开始向下搜索&#xff0c;如果一个对象到GCRoots没有任何引用链相连&#xff0c;则说明对象不可用。即给定一个集合的引用作为根出发&#xff0c;通过引用关系遍历对象图&#xff0c;能…

【转】图解phpstorm常用快捷键

转载自 https://segmentfault.com/a/1190000004225643 查询快捷键 CTRLN 查找类 CTRLSHIFTN 全局搜索文件 ,优先文件名匹配的文件 CTRLSHIFTALTN 查找php类名/变量名 ,js方法名/变量名, css 选择器 CIRLB 找变量的来源&#xff0c;跳到变量申明处 (CTRL 鼠标单击 也可以) CTRL…

HQL写topN、Spark写topN

HQL写topN用窗口函数rank() 、row_number()、dense_rank() 1、rank(),跳跃排序&#xff0c;假如第一第二相同&#xff0c;那么第三个就是3 select * from( select id, cn, score, rank() over(partition by id order by score desc)as ranks from top N ) A where ranks&…

【转】Dynamics 365 CRM 开发架构简介

目录 概览 名词解释连接到Dynamics 365 CRM Web APIOrganization service选择 - Web API vs. Organization service扩展服务端扩展应用端正文 Dynamics 365 CRM提供了多种编程模型&#xff0c;你可以灵活地按需选用最佳模式。 本文是对Dynamics 365 CRM编程模型的综述。 回…