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, 正在监听特定通知条件的前端应用发送一个通知事件. 传递给前 ...
随机推荐
- angular-ngSanitize模块-$sanitize服务详解
本篇主要讲解angular中的$sanitize这个服务.此服务依赖于ngSanitize模块. 要学习这个服务,先要了解另一个指令: ng-bing-html. 顾名思义,ng-bind-html和 ...
- 【8-20】java学习笔记02
others 初始化块在构造器前执行: 静态初始化块和实例变量显示初始化执行顺序为各自定义的位置: final类不能派生子类,final方法不可覆盖,final变量不可重新赋值: 判定值相等,Stri ...
- 【8-18】JS学习01
Source : http://www.w3school.com.cn/html 外部的 JavaScript 也可以把脚本保存到外部文件中.外部文件通常包含被多个网页使用的代码. 外部 JavaSc ...
- 如何解压.bz2文件包
.bz2 解压1:bzip2 -d FileName.bz2 解压2:bunzip2 FileName.bz2 压缩: bzip2 -z FileName .tar.bz2 解压:tar j ...
- ssi技术
html页面 <!DOCTYPE html> <html> <head> <title>测试ssi</title> <meta nam ...
- ExtJS -- ArrayStore
ArrayStore : // Store for array var myStore = new Ext.data.ArrayStore({ storeId: "arrayStore&qu ...
- thinkphp 完整配置config.php
ThinkPHP的系统配置都采用数组形式,配置文件地址:Bin/Conf/config.php CHECK_FILE_CASE -- windows环境下面的严格检查大小写. /* 项目设定 ...
- git 初始化
Git global setup git config --global user.name "杨清1" git config --global user.email " ...
- 使用APPCAN开发移动应用APP心得
要想使用APPCAN开发移动应用,首先要弄明白什么是APPCAN,APPCAN都具有哪些功能. 1.什么是APPCAN? APPCAN是正益无线公司开发的一套Hybrid混合应用开发平台(AppCan ...
- CSS3实现背景颜色渐变 摘抄
一. Webkit浏览器 (1) 第一种写法: background:-webkit-gradient(linear ,10% 10%,100% 100%, color-stop(0.14,rgb(2 ...