问题的描述

启动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. Source Insight 基本使用(2)-修改Source Insight 快捷键

    1. 首先,打开source insight主界面. 2. 选择"options->key assignments",进入快捷键设置界面. 3. 此时,可以看到快捷键设置对话 ...

  2. R获取股票数据

    R中好几个Pkg都提供了股票数据的在线下载方法,如果非得在其中找出一个最好的,那么quantmod当之无愧!举一个例子,譬如下载沪市大盘数据,代码可以是: library(quantmod)SSE & ...

  3. GridView控件隐藏列

    GridView隐藏列visible="false" 后你就无法取得这列的值了 下面是迄今为止最简洁的解决方法了. protected void GVList_RowDataBou ...

  4. 重温javascript事件机制

    以前用过一段时间的jquery感觉太方便,太强大了,各种动画效果,dom事件.创建节点.遍历.控件及UI库,应有尽有:开发文档也很多,网上讨论的问题更是甚多,种种迹象表明jquery是一个出色的jav ...

  5. mongoDB- - 2 增、删、改 操作

    1.创建数据库 语法:use database 说明:如果database不存在,就会创建database:如果存在就会切换到database 2.查看所有数据库 语法:show dbs; 说明:如果 ...

  6. HDU 2795

    题目: http://acm.hdu.edu.cn/showproblem.php?pid=2795 线段树问题,线段树的每个叶子节点保存的是当前行还剩余的长度,每次查询找到满足条件的一行减去该条幅的 ...

  7. ubuntu下如何用命令行运行deb安装包

    如果ubuntu要安装新软件,已有deb安装包(例如:iptux.deb),但是无法登录到桌面环境.那该怎么安装?答案是:使用dpkg命令. dpkg命令常用格式如下: sudo dpkg -I ip ...

  8. 汉诺塔(河内塔)算法 ----C语言递归实现

    汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具.大梵天创造世界的时候做了三根金刚石柱子, 在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘.大梵天命令婆罗门把圆盘从下面开始按大小顺 ...

  9. uploadify插件的功能应用

    一.相关key值介绍 uploader:uploadify.swf文件的相对路径,该swf文件是一个带有文字BROWSE的按钮,点击后淡出打开文件对话框,默认值:uploadify.swf. scri ...

  10. svn: E155004 'XX' is already locked

    Error:svn: E155004: Run 'svn cleanup' to remove locks (type 'svn help cleanup' for details)svn: E155 ...