Condition 将 Object 监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set (wait-set)。其中,Lock 替代了 synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用。Condition的使用必须是在lock修饰的语句块中。

下面给出一个简单的示例:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; /**
* Created by litao on 15/5/26.
*/
public class TaskTest { private boolean flag;
private int num;
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition(); public void sub() {
lock.lock();
while (flag == false) {
try {
condition.await();
} catch (Exception e) {
e.printStackTrace();
}
}
for (int i = 0; i < 5; i++) {
num--;
System.out.println("sub num:" + num);
}
flag = false;
condition.signal();
lock.unlock();
} public void add() {
lock.lock();
while (flag == true) {
try {
condition.await();
} catch (Exception e) {
e.printStackTrace();
}
}
for (int i = 0; i < 5; i++) {
num++;
System.out.println("add num:" + num);
}
flag = true;
condition.signal();
lock.unlock();
} public static void main(String[] args) { final TaskTest taskTest = new TaskTest();
Thread thread1 = new Thread() {
@Override
public void run() {
taskTest.sub();
}
};
Thread thread2 = new Thread() {
@Override
public void run() {
taskTest.add();
}
};
thread1.start();
thread2.start();
}
}

执行结果:

add num:1

add num:2

add num:3

add num:4

add num:5

sub num:4

sub num:3

sub num:2

sub num:1

sub num:0

可以看出,condition.signal()和condition.await()在这种情况下和传统的notify,wait具有相同的功效。

既然condition提供的功能和传统的方法相同,那为啥还要有这个东东呢?下面介绍condition的独特的地方。

public class Buffer {
private Lock lock = new ReentrantLock();
private Condition readCondition = lock.newCondition();
private Condition writeCondition = lock.newCondition();
private LinkedList<String> buffers;
private int size = 0;
private int maxSize; public Buffer(int maxSize) {
this.maxSize = maxSize;
buffers=new LinkedList<String>();
} public String get() {
lock.lock();
while (size == 0) {
try {
readCondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
String tmp = buffers.poll();
size = size - 1;
System.out.println(Thread.currentThread().getName()+" ,get: "+tmp);
writeCondition.signalAll();
lock.unlock();
return tmp;
} public void set(String str) {
lock.lock();
while (size == maxSize) {
try {
writeCondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
buffers.offer(str);
size = size + 1;
System.out.println(Thread.currentThread().getName()+" ,set: "+str);
readCondition.signalAll();
lock.unlock();
}
}

上面代码使一个使用了Condition实现的的Buffer。

这里将写和读分别使用了writeCondition和readCondition,相较于传统的notify,主要的区别是:使用condition可以按条件唤醒不同的线程,当可读的时候只唤醒读线程,当可写的时候只唤醒写线程。这样,不会致使某个无关的线程被唤醒后,立即又被阻塞。可以提高程序的执行效率。

使用上面Buffer,实现的一个生产者-消费者模型

import java.util.Random;

/**
* Created by litao on 15/5/26.
* 生产者-消费者模型
*/
public class ProducerAndConsumer { public static void main(String[] args) { final String[] randomStr = {
"0asaswwdwdwdw",
"1aswswswdwdwdw",
"2asasaswwdwd",
"3asaswwdwd",
"4sdsdwwdwd"
};
final Buffer buffer = new Buffer(5); final Producer producer = new Producer(buffer);
final Consumer consumer = new Consumer(buffer);
final Random random = new Random();
for (int i = 0; i < 10; i++) {
Thread thread1 = new Thread("producer" + i) {
@Override
public void run() {
int index = random.nextInt(5);
producer.produce(randomStr[index]);
}
};
thread1.start();
} for (int i = 0; i < 10; i++) {
Thread thread = new Thread("consumer" + i) {
@Override
public void run() {
String str = consumer.consum();
System.out.println("str:" + str);
}
};
thread.start();
} }
public static class Producer {
private Buffer buffer; public Producer(Buffer buffer) {
this.buffer = buffer;
} public void produce(String str) {
buffer.set(str);
}
} public static class Consumer {
private Buffer buffer; public Consumer(Buffer buffer) {
this.buffer = buffer;
} public String consum() {
return buffer.get();
}
}
}

程序执行结果:

producer0 ,set: 0asaswwdwdwdw

producer1 ,set: 0asaswwdwdwdw

producer2 ,set: 0asaswwdwdwdw

producer3 ,set: 3asaswwdwd

producer4 ,set: 2asasaswwdwd

consumer0 ,get: 0asaswwdwdwdw

producer5 ,set: 4sdsdwwdwd

str:0asaswwdwdwdw

consumer1 ,get: 0asaswwdwdwdw

str:0asaswwdwdwdw

producer6 ,set: 0asaswwdwdwdw

consumer4 ,get: 0asaswwdwdwdw

str:0asaswwdwdwdw

producer8 ,set: 1aswswswdwdwdw

consumer5 ,get: 3asaswwdwd

str:3asaswwdwd

producer9 ,set: 4sdsdwwdwd

consumer2 ,get: 2asasaswwdwd

str:2asasaswwdwd

consumer3 ,get: 4sdsdwwdwd

str:4sdsdwwdwd

producer7 ,set: 0asaswwdwdwdw

consumer6 ,get: 0asaswwdwdwdw

str:0asaswwdwdwdw

consumer7 ,get: 1aswswswdwdwdw

str:1aswswswdwdwdw

consumer8 ,get: 4sdsdwwdwd

str:4sdsdwwdwd

consumer9 ,get: 0asaswwdwdwdw

str:0asaswwdwdwdw

Condition 的使用的更多相关文章

  1. java 线程 Lock 锁使用Condition实现线程的等待(await)与通知(signal)

    一.Condition 类 在前面我们学习与synchronized锁配合的线程等待(Object.wait)与线程通知(Object.notify),那么对于JDK1.5 的 java.util.c ...

  2. MySQL 优化之 ICP (index condition pushdown:索引条件下推)

    ICP技术是在MySQL5.6中引入的一种索引优化技术.它能减少在使用 二级索引 过滤where条件时的回表次数 和 减少MySQL server层和引擎层的交互次数.在索引组织表中,使用二级索引进行 ...

  3. 0038 Java学习笔记-多线程-传统线程间通信、Condition、阻塞队列、《疯狂Java讲义 第三版》进程间通信示例代码存在的一个问题

    调用同步锁的wait().notify().notifyAll()进行线程通信 看这个经典的存取款问题,要求两个线程存款,两个线程取款,账户里有余额的时候只能取款,没余额的时候只能存款,存取款金额相同 ...

  4. 1229【MySQL】性能优化之 Index Condition Pushdown

    转自http://blog.itpub.net/22664653/viewspace-1210844/  [MySQL]性能优化之 Index Condition Pushdown2014-07-06 ...

  5. 四、线程同步之Lock和Condition

    Lock同步锁 Lock 在jdk1.5  提供了Lock以便执行同步操作,和synchronized不同的是Lock提供了显示的方法获取锁和释放锁.Lock提供了以下几个方法,请求和释放锁: voi ...

  6. 【Java并发系列04】线程锁synchronized和Lock和volatile和Condition

    img { border: solid 1px } 一.前言 多线程怎么防止竞争资源,即防止对同一资源进行并发操作,那就是使用加锁机制.这是Java并发编程中必须要理解的一个知识点.其实使用起来还是比 ...

  7. druid sql黑名单 报异常 sql injection violation, part alway true condition not allow

    最近使用druid,发现阿里这个连接池 真的很好用,可以监控到连接池活跃连接数 开辟到多少个连接数 关闭了多少个,对于我在项目中查看错误 问题,很有帮助, 但是最近发现里面 有条sql语句 被拦截了, ...

  8. 【Java并发编程实战】-----“J.U.C”:Condition

    在看Condition之前,我们先来看下面这个例子: 工厂类,用来存放.取出商品: public class Depot { private int depotSize; //仓库大小 private ...

  9. 【JAVA并发编程实战】12、使用condition实现多线程下的有界缓存先进先出队列

    package cn.study.concurrency.ch14; import java.util.concurrent.locks.Condition; import java.util.con ...

  10. spring @condition 注解

    spring @condition注解是用来在不同条件下注入不同实现的 demo如下: package com.foreveross.service.weixin.test.condition; im ...

随机推荐

  1. 所有Mac用户都需要知道的9个实用终端命令行<转>

    转自 http://www.macx.cn/thread-2075903-1-1.html 通常情况下,只有高端用户才会经常用到终端应用.这并不意味着命令行非常难学,有的时候命令行可以轻松.快速的解决 ...

  2. Factory Method 工厂方法模式

    Factory method工厂方法模式是一种实现了“工厂”概念的面向对象设计模式.就像其他创建型模式一样,它也是处理在不指定对象具体类型的情况下创建对象的问题.工厂方法模式的实质是“定义一个创建对象 ...

  3. sulime-text 3 安装以及使用

    sublime-text 3 使用了有一段时间了,虽然不是很熟悉,但是已经爱上它了,但是对这个编辑器还是一知半解,所以现在记录下,希望以后能永久的使用这个编辑器. 一,调用 控制台 使用命令 ctrl ...

  4. PHP 时间函数集合

    计算指定日期的前几天,几个月或者几年的函数 $a = '2014/08/21';echo date( "Y-m-d", strtotime( "-6 month  &qu ...

  5. 安装mysql数据库

    http://jingyan.baidu.com/article/f3ad7d0ffc061a09c3345bf0.html

  6. O-C相关04:类方法的概述与定义和调用

    类方法的概述与定义和调用 1, 类方法的概述 类方法(class method)在其他编程语言中常常称为静态方法(例如 Java 或 C# 等). 与实例方法不同的是,类方法只需要使用类名即可调用, ...

  7. [C#][转]与MySql连接访问

    using System;using System.Configuration;using MySql.Data.MySqlClient;/// <summary>/// TestDate ...

  8. 三角网格(Triangle Mesh)的理解

    最简单的情形,多边形网格不过是一个多边形列表:三角网格就是全部由三角形组成的多边形网格.多边形和三角网格在图形学和建模中广泛使用,用来模拟复杂物体的表面,如建筑.车辆.人体,当然还有茶壶等.图14.1 ...

  9. html5+css3实现上拉和下拉刷新

    <!DOCTYPE html><html><head> <meta http-equiv="Content-Type" content=& ...

  10. 如何禁用easyui-linkbutton 中的Click事件

    eg: <a id="btn" href="#" class="easyui-linkbutton" data-options=&qu ...