问题的描述

启动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 的一个优势案例分析的更多相关文章

  1. 一个bug案例分析

    Bug描述: 某大型系统的一个提供基础数据服务的子系统A进行了一次升级.升级的内容为:优化了失败重传功能,在优化的同时,开发人员发现传输数据的时间戳精度只是精确到了秒,于是顺手把精度改成了1/100秒 ...

  2. javascript一个作用域案例分析

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. 生产者消费者两种实现:wait/notifyAll和Lock/Condition

    1.wait/notifyAll /** * 面试题:写一个固定容量同步容器,拥有put和get方法,以及getCount方法, * 能够支持2个生产者线程以及10个消费者线程的阻塞调用 * * 使用 ...

  4. Java多线程——Lock&Condition

    Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象.两个线程执行的代码片段要实现同步互斥的效果,它们必须用同一个Lock对象. package ...

  5. lock+Condition

    关键字 synchronized+wait/notify/notifyAll可以实现等待/通知模式,类ReentrantLock可以实现同样的功能,但需要借助Condition对象.Condition ...

  6. Lock+Condition实现机制

    前言:大部分多线程同步场景,在功能和性能层面,synchronized可以满足,少部分场景Lock可以满足,dubbo的源码也符合这个比例,需要使用到Condition的场景极少,整个dubbo源码中 ...

  7. 【java并发编程】Lock & Condition 协调同步生产消费

    一.协调生产/消费的需求 本文内容主要想向大家介绍一下Lock结合Condition的使用方法,为了更好的理解Lock锁与Condition锁信号,我们来手写一个ArrayBlockingQueue. ...

  8. 玩转Java多线程(Lock.Condition的正确使用姿势)

    转载请标明博客的地址 本人博客和github账号,如果对你有帮助请在本人github项目AioSocket上点个star,激励作者对社区贡献 个人博客:https://www.cnblogs.com/ ...

  9. NOTIFY - 生成一个通知

    SYNOPSIS NOTIFY name DESCRIPTION 描述 NOTIFY 命令向当前数据库中所有执行过 LISTEN name, 正在监听特定通知条件的前端应用发送一个通知事件. 传递给前 ...

随机推荐

  1. UvaLive6662 The Last Ant 模拟

    UvaLive6662 PDF题目 题意:给出隧道长度L,蚂蚁数量N,各蚂蚁位置Pi.前进方向Di,都为整数(前进方向为L或R),蚂蚁速度为1cm每秒,两蚂蚁若在整数点相遇则都反向,若不在整数点相遇则 ...

  2. iOS 字符转换

    字典或者数组转化为nsstring NSArray *arr = [NSArray arrayWithObject:@"1"]; NSString *str = [arr JSON ...

  3. plt和got

    最近在学习linux高级调试技术.下面就动态库连接这块做了一个实验 首先理解下plt是procedure linkage table,got是global offset table.got表中存放的是 ...

  4. [AngularJS] 常用指令

    常用指令 ng-hide指令,用于控制部分HTML元素可见(ng-hide="false")和不可见状态(ng-hide="true"),如下: <div ...

  5. PHP读取excel文档

    PHP读取excel文档 项目需要读取Excel的内容,从百度搜索了下,主要有两个选择,第一个是PHPExcelReader,另外一个是PHPExcel.   PHPExcelReader比较轻量级, ...

  6. 今天微信群需要人家通过吗?是微信bug吗

    今天遇到微信群拉人的问题,所以来和大家取经,刚开始拉人一下就拉进去了,后来拉的需要人家通过,今天朋友些也帮我拉人也是这样的,所以想问下微信群扩容的问题.晚上有位朋友跟我说一次拉十个人,不能拉多,这样就 ...

  7. Spring的问题解决记录

    问题:在MyEclipse中项目工程重命名以后,例如 原来叫HttpService,改为GameApp,但是项目跑起来发现,tomcat服务器依旧为GameApp目录结构,访问也只能GameApp访问 ...

  8. CentOS-6.5-NFS部署

                      nfs-server与nfs-client端配置一样   NFS(network file system)网络文件系统:用于在网络上共享存储. 服务端-192.16 ...

  9. 《Lua程序设计 第二版》学习笔记一

    Lua简介 Lua是一种简单.可拓展.可移植及高效的脚本语言. 开始 Lua之间不需要分隔符 运行方式: Linux下: lua -i prog dofile("lib1.lua" ...

  10. 基于SSL协议的双向认证 - 双向认证 [3]

    1      SSL双向认证的实现 这里是基于SSL和Tomcat配置实现的,配置方法如下: 1.1    生成CA数字证书 首先需要配置OPENSSL环境变量. 我的OPENSSL配置文件路径是“D ...