Java多线程开发之~~~多条件Condition接口的使用

2023-05-16

我们在多线程开发中,可能会出现这种情况。就是一个线程需要另外一个线程满足某某条件才能继续运行,或者需

要其他线程满足好几个条件才能运行,对于这样的多条件的多线程并发,我们如何控制好各个线程之间的关系,使他们

能很好的处理冲突不至于相互出现问题呢,下面我们来介绍一下Java提供的Condition这个接口,这个接口很好的实现了

这种需求。

对于这个问题最经典的例子就是生产者消费者模型,生产者当缓冲区满的时候不生产商品知道缓冲区有空余,消费

者当缓冲区为0 的时候不拿商品,直到生产者向缓冲区放入商品,下面我们使用Conditon这个接口来实现这样的需求。


package com.bird.concursey.charpet4;

/**
 * First, let's implement a class that will simulate a text file. Create a class named
FileMock with two attributes: a String array named content and int named
index. They will store the content of the file and the line of the simulated file that will
be retrieved.
 * @author bird
 * 2014年9月21日 下午6:55:31
 */
public class FileMock {
	
	private String content[];
	private int index;
	
	/**
	 * Implement the constructor of the class that initializes the content of the file with
random characters.
	 * @param size
	 * @param length
	 */
	public FileMock(int size, int length) {
		content = new String[size];
		for(int i = 0; i < size; i++) {
			StringBuilder buffer = new StringBuilder(length);
			for(int j = 0; j < length; j++) {
				int indice = (int) (Math.random() * 255);
				buffer.append((char)indice);
			}
			content[i] = buffer.toString();
		}
		index = 0;
	}
	
	/**
	 * Implement the method hasMoreLines() that returns true if the file has more lines
to process or false if we have achieved the end of the simulated file.
	 * @return
	 */
	public boolean hasMoreLines() {
		return index < content.length;
	}
	
	/**
	 * Implement the method getLine() that returns the line determined by the index
attribute and increases its value.
	 * @return
	 */
	public String getLine() {
		if(this.hasMoreLines()) {
			System.out.println("Mock: " + (content.length - index));
			return content[index++];
		}
		return null;
	}
}



package com.bird.concursey.charpet4;

import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * implement a class named Buffer that will implement the buffer shared by
 * producers and consumers.
 * 
 * @author bird 2014年9月21日 下午6:58:13
 */
public class Buffer {

	private LinkedList<String> buffer;
	private int maxSize;
	private ReentrantLock lock;
	private Condition lines;
	private Condition space;
	private boolean pendingLines;
	
	/**
	 * Implement the constructor of the class. It initializes all the attributes
described previously.
	 * @param maxSize
	 */
	public Buffer(int maxSize) {
		this.maxSize = maxSize;
		buffer = new LinkedList<String>();
		lock = new ReentrantLock();
		lines = lock.newCondition();
		space = lock.newCondition();
		pendingLines = true;
	}
	
	/**
	 * Implement the insert() method. It receives String as a parameter and tries
to store it in the buffer. First, it gets the control of the lock. When it has it, it then
checks if there is empty space in the buffer. If the buffer is full, it calls the await()
method in the space condition to wait for free space. The thread will be woken up
when another thread calls the signal() or signalAll() method in the space
Condition. When that happens, the thread stores the line in the buffer and calls
the signallAll() method over the lines condition. As we'll see in a moment, this
condition will wake up all the threads that were waiting for lines in the buffer.
	 * @param line
	 */
	public void insert(String line) {
		lock.lock();
		try {
			while(buffer.size() == maxSize) {
				space.await();
			}
			buffer.add(line);
			System.out.printf("%s: Inserted Line: %d\n", Thread.currentThread().getName(),buffer.size());
			lines.signalAll();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}finally{
			lock.unlock();
		}
	}
	
	/**
	 * Implement the get() method. It returns the first string stored in the buffer. First, it
gets the control of the lock. When it has it, it checks if there are lines in the buffer.
If the buffer is empty, it calls the await() method in the lines condition to wait
for lines in the buffer. This thread will be woken up when another thread calls the
signal() or signalAll() method in the lines condition. When it happens, the
method gets the first line in the buffer, calls the signalAll() method over the
space condition and returns String.
	 * @return
	 */
	public String get() {
		String line = null;
		lock.lock();
		try {
			while((buffer.size() == 0) && (hasPendingLines())) {
				lines.await();
			}
			if(hasPendingLines()) {
				line = buffer.poll();
				System.out.printf("%s: Line Readed: %d\n",Thread.currentThread().getName(),buffer.size());
				space.signalAll();
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}finally{
			lock.unlock();
		}
		return line;
	}
	
	/**
	 * Implement the setPendingLines() method that establishes the value of the
attribute pendingLines. It will be called by the producer when it has no more lines
to produce.
	 * @param pendingLines
	 */
	public void setPendingLines(boolean pendingLines) {
		this.pendingLines=pendingLines;
	}
	
	/**
	 * Implement the hasPendingLines() method. It returns true if there are more lines
to be processed, or false otherwise.
	 * @return
	 */
	public boolean hasPendingLines() {
		return pendingLines || buffer.size() > 0;
	}
}


package com.bird.concursey.charpet4;

public class Producer implements Runnable {
	
	private FileMock mock;
	
	private Buffer buffer;
	
	public Producer(FileMock mock, Buffer buffer) {
		this.mock = mock;
		this.buffer = buffer;
	}

	/**
	 * Implement the run() method that reads all the lines created in the FileMock
object and uses the insert() method to store them in the buffer. Once it finishes,
use the setPendingLines() method to alert the buffer that it's not going to
generate more lines.
	 */
	@Override
	public void run() {
		buffer.setPendingLines(true);
		while(mock.hasMoreLines()) {
			String line = mock.getLine();
			buffer.insert(line);
		}
		buffer.setPendingLines(false);
	}

}


package com.bird.concursey.charpet4;

import java.util.Random;

public class Consumer implements Runnable {
	
	private Buffer buffer;
	
	public Consumer(Buffer buffer) {
		this.buffer = buffer;
	}

	/**
	 * Implement the run() method. While the buffer has pending lines, it tries to get one
and process it.
	 */
	@Override
	public void run() {
		while(buffer.hasPendingLines()) {
			String line = buffer.get();
			processLine(line);
		}
	}
	
	/**
	 * Implement the auxiliary method processLine(). It only sleeps for 10 milliseconds
to simulate some kind of processing with the line.
	 * @param line
	 */
	private void processLine(String line) {
		Random random = new Random();
		try {
			Thread.sleep(random.nextInt(100));
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		FileMock fileMock = new FileMock(100, 10);
		Buffer buffer = new Buffer(20);
		
		Producer producer = new Producer(fileMock, buffer);
		Thread threadProducer = new Thread(producer, "Producer");
		
		Consumer consumers[] = new Consumer[3];
		Thread threadConsumers[] = new Thread[3];
		for(int i = 0; i < 3; i++) {
			consumers[i] = new Consumer(buffer);
			threadConsumers[i] = new Thread(consumers[i], "consumer " + i);
		}
		
		threadProducer.start();
		for(int i = 0; i < 3; i++) {
			threadConsumers[i].start();
		}
	}

}


注意:

When a thread calls the await() method of a condition, it automatically frees the control of the lock, so that another thread can get it and begin the execution of the same, or another critical section protected by that lock.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java多线程开发之~~~多条件Condition接口的使用 的相关文章

  • Android平台上如何让应用程序获得系统权限以及如何使用platform密钥给apk签名

    您好 xff0c 欢迎关注我的专栏 xff0c 本篇文章是关于 Flutter 的系列文 xff0c 从简单的 Flutter 介绍开始 xff0c 一步步带你了解进入 Flutter 的世界 你最好有一定的移动开发经验 xff0c 如果没
  • Android 11 Settings源码入门,我就不信你还听不明白了

    前言 曾听过很多人说Android学习很简单 xff0c 做个App就上手了 xff0c 工作机会多 xff0c 毕业后也比较容易找工作 这种观点可能是很多Android开发者最开始入行的原因之一 在工作初期 xff0c 工作主要是按照业务
  • Linux破解密码

    1 重启虚拟机 xff0c 在引导界面按 e xff08 按鼠标左键 xff0c 用键盘控制上下 xff09 xff0c 进入类界面 xff0c 把中间的ro改为 rw rd break 2 按住Ctrl 43 x xff0c 进入紧急界面
  • “移除”虚拟机和“从磁盘中删除”虚拟机的区别

    1 二者的区别 xff1a 移除 虚拟机操作只是在虚拟机上删除了 xff0c 并没有在Windows系统中删除相关文件 xff0c 是部分删除 xff1b 而 从磁盘中删除 是既在虚拟机上删除了 xff0c 也删除了Windows系统中的相
  • Linux常用命令

    一条命令的结构 xff1a 用户名 64 主机名 工作目录 提示符 lt 命令 gt 选项 参数1 参数2 一 文件操作类命令 1 touch命令 xff1a 用于建立文件或更新文件的修改日期 1 语法格式 xff1a touch 参数 文
  • 内部类

    链接 xff1a https www nowcoder com questionTerminal 48524c47dd924887be6684b17175fa40 1 为什么使用内部类 使用内部类最吸引人的原因是 xff1a 每个内部类都能
  • CentOS 8本地离线YUM源的配置

    1 准备好CentOS 8相同版本号的系统镜像文件 2 添加光驱硬件 xff0c 在光驱中调用iso镜像文件 xff08 具体操作 xff1a 先打开设置里面的CD DVD xff0c 再点击使用ISO镜像文件 xff0c 选择浏览会跳转到
  • Linux操作系统:管理用户和组

    任务一 xff1a Linux用户类型和组群 1 Linux系统下的用户账户分为三种 超级用户 xff08 root xff09 xff1a 拥有系统的最高权限 xff0c 可以不受限制的对任何文件和命令进行操作 xff0c 对系统具有绝对
  • 在CentOS_8中添加新的硬盘

    添加新硬盘的具体步骤 xff1a 第一步 xff1a 第二步 xff1a 第三步 xff1a xff08 注意 xff1a 这里选择 SATA A xff0c 其优点是可随时使用 xff0c 无需重启 xff1b 而 SCSI S 需要重启
  • Linux下生产者消费者模型

    Linux下生产者消费者模型 一 什么是生产者消费者模型二 代码实现三 运行结果与修改 一 什么是生产者消费者模型 生产者消费者模型就是通过一个容器来解决生产者和消费者的强耦合问题 生产者和消费者彼此之间不直接通讯 xff0c 而通过阻塞队
  • 开发一个支持跨平台的 Kotlin 编译器插件

    前言 前面简单介绍了一下Kotlin编译器插件是什么 xff0c 以及如何一步一步开发一个Kotlin编译器插件 xff0c 但是之前开发的编译器插件是通过修改字节码的方式来修改产物的 xff0c 只支持JVM平台 今天主要在此基础上 xf
  • 逆变器原理

    逆变器是把直流电转变为交流电的一种装置 它一般包括逆变桥 控制逻辑和滤波电路组成 主要是把各种直流源转变为交流供交流负载使用 xff0c 一般直流源有蓄电池 干电池 太阳能电池等 xff0c 可以应用到不间断电源 UPS 太阳能发电转换等
  • Linux网络编程

    目录 网络编程基础 Internet历史 TCP IP协议基本概念 网络体系结构 TCP IP体系结构 TCP IP协议知识要点 TCP协议和UDP协议 网络编程预备知识 基于TCP协议的网络编程案例 基于UDP协议的服务器客户端编写 1
  • Android12动态控制SystemUI状态栏和导航栏

    要实现一个需求 在Android12上实现动态控制状态栏和导航栏的显示及隐藏 基本思路 在frameworks base 中增加想要的显示控制 在Settings增加开关按钮进行功能出发 一 在framework base 增加系统属性 用
  • Java—反射详解

    1 反射概念 反射本质就是反着来 反射 Reflection 是Java的特征之一 xff0c 它允许运行中的Java程序获取自身的信息 xff0c 并且可以操作类或对象的内部属性 通俗的来讲就是 xff1a 通过反射机制 xff0c 可以
  • png图片损坏打不开如何修复?

    png格式是我们生活中常用的格式 xff0c 可以用于存储不同的网络图形 数码照片和背景透明的图像 但常用的PNG文件格式有时也会有损坏的 xff0c 在这种情况下 xff0c 要保持冷静 xff0c 发现后先不要去尝试打开这些图片 xff
  • cookie与session

    a 什么是cookie 浏览器在访问服务器时 xff0c 服务器将一些数据以set cookie 消息头 的形式发送给浏览器 浏览器会将这些数据保存起来 当浏览器再次访问服务器时 xff0c 会将这些数据以cookie消息头的形式发送给服务
  • GithubDNS解析配置

    hosts文件位置 xff1a Windows 系统 xff1a C Windows System32 drivers etc hosts 复制以下代码 xff1a GitHub520 Host Start 140 82 114 26 al
  • java:如何判断一个链表是否成环,并找到成环的位置

    面试题型 xff1a 判断一个链表中是否成环 思路 xff1a 定义两个快慢指针 xff0c 让他们一直移动 xff0c 如果最终快指针 61 慢指针 xff0c 这说明在这个链表中必然存在环 首先 xff0c 将快指针定义为fast 慢指
  • 基于zynq7000平台的vxWorks6.9移植(上)

    1 致谢 编写本文档的目的在于指导用户如何移植基于z7平台的vxWorks6 9系统 移植之前首先感谢西安迅尔电子嵌入式工程师庞国强 xff0c 本次是基于前者总结资料的基础上进行的完善 xff0c 帮助新手可以以更少的指导掌握z7平台关于

随机推荐

  • Python新建、写入和修改txt(文本文档)

    新建 写入 xff1a 创建一个txt文件 xff0c 文件名为first file 并向文件写入msg def File New name msg desktop path 61 34 路径 34 文件路径 full path 61 de
  • 面试突击:输入URL之后会执行什么流程?

    在浏览器中输入 URL 之后 xff0c 它会执行以下几个流程 xff1a 执行 DNS 域名解析 xff1b 封装 HTTP 请求数据包 xff1b 封装 TCP 请求数据包 xff1b 建立 TCP 连接 xff08 3 次握手 xff
  • 面试官:Spring Aop 常见注解和执行顺序

    最近 xff0c 我在给很多人做简历修改和模拟面试的时候 xff0c 有部分朋友和我反馈Spring AOP的面试题 xff0c 今天就和大家来问问 Spring 一开始最强大的就是 IOC AOP 两大核心功能 xff0c 我们今天一起来
  • Microsoft Visual C++ 14.0下载方法

    去官网下载对应的文件 xff08 需要拥有一个微软的账号 xff09 首先 xff0c 打开链接首页 Visual Studio Subscriptions Portal xff0c 登录账号 xff0c 点击进入下载页面 接下来 xff0
  • Zabbix6.0离线安装(附RPM包)

    zabbix server6 0安装包及依赖 一 准备工作 xff1a 虚拟环境软件VMware Workstation 17 pro xff0c 可以根据自身需求来选择 xff0c VMware下载链接参考如下 xff1a https c
  • java中try 与catch的使用

    try 代码区 catch Exception e 异常处理 代码区如果有错误 xff0c 就会返回所写异常的处理 首先要清楚 xff0c 如果没有try的话 xff0c 出现异常会导致程序崩溃 而try则可以保证程序的正常运行下去 xff
  • 基于JAVA京津冀畅游网设计计算机毕业设计源码+数据库+lw文档+系统+部署

    基于JAVA京津冀畅游网设计计算机毕业设计源码 43 数据库 43 lw文档 43 系统 43 部署 基于JAVA京津冀畅游网设计计算机毕业设计源码 43 数据库 43 lw文档 43 系统 43 部署 本源码技术栈 xff1a 项目架构
  • JSP 四大作用域:

    application对象中的属性可以被同一个WEB应用程序中的所有Servlet和JSP页面访问 xff08 属性作用范围最大 xff09 session对象中的属性可以被属于同一个会话的所有Servlet和JSP页面访问 xff08 适
  • django基于Python的疫情数据可视化分析系统的设计与实现(源码调试+代码讲解+文档报告)

    x1f495 x1f495 作者 xff1a 计算机源码社 x1f495 x1f495 个人简介 xff1a 本人七年开发经验 xff0c 擅长Java 微信小程序 Python Android等 xff0c 大家有这一块的问题可以一起交流
  • 基于SSM+Vue个人健康信息管理系统Java个人健康状况记录与评估系统(源码调试+讲解+文档)

    x1f495 x1f495 作者 xff1a 计算机源码社 x1f495 x1f495 个人简介 xff1a 本人七年开发经验 xff0c 擅长Java 微信小程序 Python Android等 xff0c 大家有这一块的问题可以一起交流
  • DBSCAN聚类——Python实现

    一 DBSCAN Density Baseed Spatial Clustering of Applications with Noise 聚类算法 核心对象 xff1a 若某个点的密度达到算法设定的阈值则其为核心 xff08 即r邻域内点
  • 解决ubuntu操作系统默认没有创建root账户

    解决ubuntu操作系统默认没有创建root账户 xff1a 1 sudo passwd root重置root密码 会提示输入当前用户密码 xff0c 然后重新设置新密码 2 设置成功之后su root得到root登陆
  • hexo+github个人博客搭建(亲身经历超详解)

    Hexo 是一个快速 简洁且高效的博客框架 Hexo 使用 Markdown xff08 或其他渲染引擎 xff09 解析文章 xff0c 在几秒内 xff0c 即可利用靓丽的主题生成静态网页 本文章适用于windows系统搭建 xff0c
  • 数论----质数的求解(C/C++)

    CSDN的uu xff0c 你们好呀 xff0c 今天我们要学习的内容是 数论 哦 xff01 这也是算法题中的一类题目吧 记好安全带 xff0c 准备发车咯 xff01 x1f680 学习数论的意义 x1f4e2 算法导论说 xff1a
  • 源代码是指什么?

    源代码是指以特定编程语言编写的文本文件 xff0c 用于控制软件 硬件 计算机程序或系统 源代码是代表软件不同功能的一类 指令 下面我将详细说明源代码的定义 首先要说的是 xff0c 源代码是建立在编程语言之上的文本文件 它可用于编写程序
  • Java 中如何优化大量的 if...else...

    策略模式 xff08 Strategy Pattern xff09 将每个条件分支的实现作为一个独立的策略类 xff0c 然后使用一个上下文对象来选择要执行的策略 这种方法可以将大量的if else语句转换为对象之间的交互 xff0c 从而
  • Selenium+Pytest自动化测试框架实战,还不会点这里一清二楚,全网最细教程!

    如果下方文字内容没有看明白的话 xff0c 我推荐大家看一套视频 xff0c 比文字内容讲的更加详细 xff01 在华为工作了10年的大佬出的Web自动化测试教程 xff0c 华为现用技术教程 xff01 哔哩哔哩 bilibili 在华为
  • node(编写结构化程序)

    node js的使用 console log 39 小邹最黑 39 使用js文件 去执行NodeJS代码 掌握 1 在代码文件夹中 新建js文件 不要新建成html 里面写任意js代码 const skill 61 39 喵喵拳 39 co
  • ubuntu操作系统查看已安装的包

    dpkg的介绍 dpkg 是 Debian Packager 的简写 为 Debian 专门开发的套件管理系统 xff0c 方便软件的安装 更新及移除 所有源自 Debian 的 Linux 发行版都使用 dpkg xff0c 例如 Ubu
  • Java多线程开发之~~~多条件Condition接口的使用

    我们在多线程开发中 xff0c 可能会出现这种情况 就是一个线程需要另外一个线程满足某某条件才能继续运行 xff0c 或者需 要其他线程满足好几个条件才能运行 xff0c 对于这样的多条件的多线程并发 xff0c 我们如何控制好各个线程之间