java多线程-线程间协作
大纲:
- wait、notify、notifyAll
- Condition
- 生产消费者
一、wait、notify、notifyAll
- wait、notify、notifyAll是Object的本地final方法。
- 在一个线程中调用object.wait()可以使当先线程阻塞并交出锁(object)。
- 既然obj.wait操作会交出锁,那必然在synchronized(obj)代码块内,且2个obj为统一对象。
- 使用obj.notify()能够唤醒任意一个等待obj锁的线程,obj.notifyAll()能够唤醒所有等待obj锁的线程。同样notify操作也必须在synchronized(obj)代码块内。
- 线程等待是锁对象的方法而不是线程的方法,试想在多个synchronized嵌套代码块内,调用wait()是不是应该指定释放哪一个锁对象。
二、Condition
- Condition接口依赖于Lock接口,可以通过lock.newCondition() 。
- wait,notify操作都是控制一个锁下面的线程。Condition可以将一个锁下面的线程分成多种情况分别控制。
- 调用Condition的await()和signal()方法也需要在lock()-unlock()代码块内。
- Condition接口的await对应Object的wait方法 ,signal对应notify方法 ,signalAll对应notifyAll方法 。
- 使用Condition也更加高效。
- void awaitUninterruptibly():不响应中断的await方法。
- long awaitNanos(long nanosTimeout) throws InterruptedException:await上增加超时响应,返回值=nanosTimeout-消耗时间。
三、生产消费者
生产者、消费者线程轮流执行,操作同一个资源。
消费者:
public class Comsumer implements Runnable {
Resource resource;
public Comsumer(Resource resource){
this.resource = resource;
}
@Override
public void run() {
try {
resource.comsume();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
生产者:
public class Producer implements Runnable {
Resource resource;
public Producer(Resource resource){
this.resource = resource;
}
@Override
public void run() {
try {
resource.produce();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
资源对象-wait,notify实现:
public class Resource {
private int r = 0;
private Object lock = new Object();
private boolean produced = false;
public void produce() throws InterruptedException {
synchronized(lock){
while (true){
while (produced){
lock.wait();
}
r++;
System.out.println(Thread.currentThread().getName()+"线程成产1个,当前剩余:"+r);
produced = true;
lock.notifyAll();
}
}
}
public void comsume() throws InterruptedException {
synchronized(lock){
while (true){
while (!produced){
lock.wait();
}
r--;
System.out.println(Thread.currentThread().getName()+"线程消费1个,当前剩余:>>"+r);
produced = false;
lock.notifyAll();
}
}
}
}
资源对象-condition实现:
public class Resource {
private int r = 0;
private boolean produced = false;
Lock lock = new ReentrantLock();
Condition proCondition = lock.newCondition();
Condition comCondition = lock.newCondition();
public void produce() throws InterruptedException {
lock.lock();
try {
while (true){
while (produced){
proCondition.await();
}
r++;
System.out.println(Thread.currentThread().getName()+"线程成产1个,当前剩余:"+r);
produced = true;
comCondition.signal();
}
}finally {
lock.unlock();
}
}
public void comsume() throws InterruptedException {
lock.lock();
try {
while (true){
while (!produced){
comCondition.await();
}
r--;
System.out.println(Thread.currentThread().getName()+"线程消费1个,当前剩余:>>"+r);
produced = false;
proCondition.signal();
}
}finally {
lock.unlock();
}
}
}
测试类
class TestWait {
public static void main(String[] args) {
Resource r = new Resource();
Producer producer = new Producer(r);
Comsumer comsumer = new Comsumer(r);
new Thread(producer).start();
new Thread(producer).start();
new Thread(producer).start();
new Thread(comsumer).start();
new Thread(comsumer).start();
new Thread(comsumer).start();
}
}
java多线程-线程间协作的更多相关文章
- Java并发--线程间协作的两种方式:wait、notify、notifyAll和Condition
在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者模型:当队列满时,生产者需要等待队列有空间才能继续往里面放入商品,而在等待的期间内,生产者必须释放对临界 ...
- Java多线程——线程间通信
Java多线系列文章是Java多线程的详解介绍,对多线程还不熟悉的同学可以先去看一下我的这篇博客Java基础系列3:多线程超详细总结,这篇博客从宏观层面介绍了多线程的整体概况,接下来的几篇文章是对多线 ...
- Java多线程之线程的状态以及线程间协作通信导致的线程状态转换
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6561589.html 一:线程的状态以及变化图 Java中线程中状态可分为五种:New(新建状态),Ru ...
- java并发编程 线程间协作
线程间协作 1. 等待和通知 等待和通知的标准形式 等待方: 获取对象锁 循环中判断条件是否满足,不调用wait()方法 条件满足执行业务逻辑 通知方: 获取对象所 改变条件 通知所有等待在对象的线程 ...
- Java中详述线程间协作
线程协作 首先引入一段代码: package 线程间数据共享; import java.util.Date; public class Watch { private static String ti ...
- Java并发编程:线程间协作的两种方式:wait、notify、notifyAll和Condition
Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition 在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者 ...
- Java并发编程(十三)线程间协作的两种方式:wait、notify、notifyAll和Condition
在现实中,需要线程之间的协作.比如说最经典的生产者-消费者模型:当队列满时,生产者需要等待队列有空间才能继续往里面放入商品,而在等待的期间内,生产者必须释放对临界资源(即队列)的占用权.因为生产者如果 ...
- 多线程之线程间协作的两种方式:wait、notify、notifyAll和Condition
Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition 在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者 ...
- Java并发编程(九)线程间协作(下)
上篇我们讲了使用wait()和notify()使线程间实现合作,这种方式很直接也很灵活,但是使用之前需要获取对象的锁,notify()调用的次数如果小于等待线程的数量就会导致有的线程会一直等待下去.这 ...
随机推荐
- Spring框架总结(四)
对象依赖关系 Spring中,如何给对象的属性赋值? [DI, 依赖注入] 1) 通过构造函数 2) 通过set方法给属性注入值 3) p名称空间 4)自动装配(了解) 5) 注解 一.对象属性赋值 ...
- Javascript 控制 让输入框不能输入 数字
监听keypress事件.判断如果是数字的话阻止浏览器冒泡 <input type="text" id="test"> <script typ ...
- js阿拉伯数字转中文大写 方法重多
方法一 function DX(n) { if (!/^(0|[1-9]\d*)(\.\d+)?$/.test(n)) return "数据非法"; var unit = &qu ...
- 【Linux】GDB调试工具
GDB调试工具 Linux中包含一个很强大的调试工具GDB(GNU Debuger),可以用它来调试C和C++程序. 一. GDB的主要功能有: 设置断点,当程序运行到断点处暂停 显示变量的值,可以打 ...
- 【微服务架构】SpringCloud之Hystrix断路器(六)
一:什么是Hystrix 在分布式环境中,许多服务依赖项中的一些将不可避免地失败.Hystrix是一个库,通过添加延迟容差和容错逻辑来帮助您控制这些分布式服务之间的交互.Hystrix通过隔离服务之间 ...
- Oracle 表关联性 Update 语句的改写,推荐改写方法1
同事写了一个逻辑稍复杂的Update 语句,觉得在代码可读性上有些转圈,交给我帮忙改下. 以下根据原SQL,使用两种方法进行改写,个人推荐方法1的改写.方法2拆分两个SQL来写,代码可读性最强,但是S ...
- Reporting Service服务SharePoint集成模式安装配置(5、安装 SQL SERVER 2012 SP1产品)
有过SQL2012 数据库安装经验的,可以跳过这一步骤直接进入第五步骤:RS外接程序的安装 数据库安装工具:SQLServer2012 SP1 Name:SQLServer2012SP1-FullS ...
- 基于python+selenium的框架思路(二)
一.如下是用例格式,第一个sheet为用例汇总,后面的sheet为具体的用例步骤 sheet:测试用例 sheet:搜索 sheet:刘江博客验证 二.读取该excel文件取出关键字等信息,作为关键字 ...
- WPF 简洁的主界面
用的是dev的TileLayouotControl控件. <dxwui:PageAdornerControl Header="" Padding="30" ...
- leetcode 31. Next Permutation JAVA
题目: 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). 必须原地修改,只允许使用额外常数 ...