Lock+Condition 相对于 wait+notify 的一个优势案例分析
问题的描述
启动3个线程打印递增的数字, 线程1先打印1,2,3,4,5, 然后是线程2打印6,7,8,9,10, 然后是线程3打印11,12,13,14,15. 接着再由线程1打印16,17,18,19,20....以此类推, 直到打印到45.
wait+notify实现:
package com.tonyluis;
public class NumberPrintDemo {
static int n = 1;
static int state = 0;
public static void main(String[] args) {
new Thread(new MyThread(0)).start();
new Thread(new MyThread(1)).start();
new Thread(new MyThread(2)).start();
}
} class MyThread implements Runnable{
private int state;
MyThread(){
this(0);
}
MyThread(int state){
this.state=state;
}
public void run() {
String threadName=Thread.currentThread().getName();
for (int i = 0; i < 3; i++) {
synchronized (MyThread.class) {
while (state != NumberPrintDemo.state)
try {
MyThread.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int j = 0; j < 5; j++)
System.out.println(threadName+ ": " + NumberPrintDemo.n++);
System.out.println();
NumberPrintDemo.state++;
NumberPrintDemo.state%=3;
MyThread.class.notifyAll();
}
}
}
}
Lock+condition实现:
package com.tonyluis;
import java.util.concurrent.locks.*;
public class NumberPrint {
static int state = 0;
static int n = 1;
static Lock lock = new ReentrantLock();
static Condition condition[]=new Condition[3];
public static void main(String[] args) {
for(int i=0;i<condition.length;i++)
condition[i]=lock.newCondition();
NumberPrint np=new NumberPrint(); new Thread(np.new MyThread(0)).start();
new Thread(np.new MyThread(1)).start();
new Thread(np.new MyThread(2)).start();
} class MyThread implements Runnable{
private int state;
MyThread(){
this(0);
}
MyThread(int state){
this.state=state;
}
public void run() {
String threadName=Thread.currentThread().getName();
for (int i = 0; i < 7; i++) {
//不需要放到finnally{}中释放锁,因为后面await()会释放锁
NumberPrint.lock.lock();
while (state != NumberPrint.state)
try {
NumberPrint.condition[state].await();
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int j = 0; j < 5; j++)
System.out.println(threadName+ ": " + NumberPrint.n++);
System.out.println();
NumberPrint.state++;
NumberPrint.state%=NumberPrint.condition.length;
NumberPrint.condition[NumberPrint.state].signal();
try {
NumberPrint.condition[state].await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
使用wait+notify的实现方式,在线程0进入notifyAll()方法之后,会唤醒线程1和线程2,线程1和线程2以及线程0会展开竞争,虽然最终是由线程1获得琐,过程可能比较曲折。
使用lock+condition的实现方法,线程0只会唤醒线程1,同时进入await()方法释放锁,这样只有线程1能够执行,非常的精确,尤其是并发量比较大的情况下。
Lock+Condition 相对于 wait+notify 的一个优势案例分析的更多相关文章
- 一个bug案例分析
Bug描述: 某大型系统的一个提供基础数据服务的子系统A进行了一次升级.升级的内容为:优化了失败重传功能,在优化的同时,开发人员发现传输数据的时间戳精度只是精确到了秒,于是顺手把精度改成了1/100秒 ...
- javascript一个作用域案例分析
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 生产者消费者两种实现:wait/notifyAll和Lock/Condition
1.wait/notifyAll /** * 面试题:写一个固定容量同步容器,拥有put和get方法,以及getCount方法, * 能够支持2个生产者线程以及10个消费者线程的阻塞调用 * * 使用 ...
- Java多线程——Lock&Condition
Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象.两个线程执行的代码片段要实现同步互斥的效果,它们必须用同一个Lock对象. package ...
- lock+Condition
关键字 synchronized+wait/notify/notifyAll可以实现等待/通知模式,类ReentrantLock可以实现同样的功能,但需要借助Condition对象.Condition ...
- Lock+Condition实现机制
前言:大部分多线程同步场景,在功能和性能层面,synchronized可以满足,少部分场景Lock可以满足,dubbo的源码也符合这个比例,需要使用到Condition的场景极少,整个dubbo源码中 ...
- 【java并发编程】Lock & Condition 协调同步生产消费
一.协调生产/消费的需求 本文内容主要想向大家介绍一下Lock结合Condition的使用方法,为了更好的理解Lock锁与Condition锁信号,我们来手写一个ArrayBlockingQueue. ...
- 玩转Java多线程(Lock.Condition的正确使用姿势)
转载请标明博客的地址 本人博客和github账号,如果对你有帮助请在本人github项目AioSocket上点个star,激励作者对社区贡献 个人博客:https://www.cnblogs.com/ ...
- NOTIFY - 生成一个通知
SYNOPSIS NOTIFY name DESCRIPTION 描述 NOTIFY 命令向当前数据库中所有执行过 LISTEN name, 正在监听特定通知条件的前端应用发送一个通知事件. 传递给前 ...
随机推荐
- android自定义控件(4)-自定义水波纹效果
一.实现单击出现水波纹单圈效果: 照例来说,还是一个自定义控件,观察这个效果,发现应该需要重写onTouchEvent和onDraw方法,通过在onTouchEvent中获取触摸的坐标,然后以这个坐标 ...
- HTML中head头结构
HTML head 头部分的标签.元素有很多,涉及到浏览器对网页的渲染,SEO等等,而各个浏览器内核以及各个国内浏览器厂商都有些自己的标签元素,这就造成了很多差异性.移动互联网时代,head 头部结构 ...
- $(document).ready(){}、$(fucntion(){})、(function(){})(jQuery)onload()的区别
1.首先说JQuery的几个写法 $(function(){ //do someting }); $(document).ready(function(){ //do so ...
- .NET中的工作目录一览!
定义: 当前工作目录——进行某项操作的目的目录,会随着OpenFileDialog.SaveFileDialog等对象所确定的目录而改变. 当前执行目录——该进程从中启动的目录,即文件自身 ...
- tc 146 2 BridgeCrossing(n人过桥问题)
SRM 146 2 1000BridgeCrossing Problem Statement A well-known riddle goes like this: Four people are c ...
- 大数据之nutch
一.nutch简介 nutch是大名鼎鼎的Doug Cutting发起的爬虫项目,nutch孵化了现在大数据处理框架Hadoop.在nutch V 0.8.0 版本之前,Hadoop是nutch的一部 ...
- 采用Atlas+Keepalived实现MySQL读写分离、读负载均衡【转载】
文章 原始出处 :http://sofar.blog.51cto.com/353572/1601552 ============================================== ...
- redis-key2
package com.ztest.redis; import java.util.List; import redis.clients.jedis.Jedis; import com.sun.ist ...
- JVM内存监控工具 Jvisualvm
这个工具是官方提供的,直接在JDK工具包下的bin目录找找就可以找到,或者打开cmd直接输入"jvisualvm"即可打开该工具(配置好java环境变量). 需要在catalina ...
- [Asp.net MVC]Asp.net MVC5系列——添加模型
目录 概述 添加模型 总结 系列文章 [Asp.net MVC]Asp.net MVC5系列——第一个项目 [Asp.net MVC]Asp.net MVC5系列——添加视图 概述 在本节中我们将追加 ...