关键字 synchronized+wait/notify/notifyAll可以实现等待/通知模式,类ReentrantLock可以实现同样的功能,但需要借助Condition对象。Condition类是JDK5中出现的技术,使用它有更好的灵活性,比如可以实现多路通知功能,选择性的进行线程通知,在调度线程上更加灵活。

使用wait+notify/notifyAll方法进行通知时,被通知的线程却是由JVM随机选择的。但使用reentrantLock结合Condition类是可以实现选择性通知。

Object类中的wait()方法,相当于Condition类中的await()方法;Object类中的notify()方法,相当于Condition类中的signal()方法。Object类中的notifyAll方法,相当于Condition类中的signalAll()方法。

打印 12A34B.......5152Z

 import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class Print12A_RC { private Lock lock =new ReentrantLock();
private Condition con=lock.newCondition();
private boolean isInt=true;
private int i=1;
private char ch ='A';
public void printInt()
{
try {
lock.lock();
while(!isInt)
{
con.await();
}
System.out.print((i++)+""+(i++));
isInt=false;
con.signal();
} catch (Exception e) {
}
finally
{
lock.unlock();
}
} public void printChar()
{
try {
lock.lock();
while(isInt)
{
con.await();
}
System.out.print((char)ch);
ch++;
isInt=true;
con.signal(); } catch (Exception e) {
}
finally {
lock.unlock();
}
} public static void main(String[] args) {
Print12A_RC rc=new Print12A_RC();
Thread aThread=new Thread(new Runnable() { @Override
public void run() {
for(int i=0;i<26;i++)
{
rc.printInt();
}
}
});
Thread bThread =new Thread(new Runnable() { @Override
public void run() {
for(int i=0;i<26;i++)
{
rc.printChar();
}
}
});
aThread.start();
bThread.start();
}
}

顺序打印,如123123123....

 package multiMethod.reentrantLockCondition;

 import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock; public class PrintByOrder {
ReentrantLock lock =new ReentrantLock();
Condition condition=lock.newCondition();
int printnext=1; public void print1()
{
lock.lock();
try{
while(printnext!=1)
{
condition.await();
}
Thread.sleep(500);//不加此行会不打印,不知什么原因。
System.out.print(1);
printnext=2;
condition.signalAll();
}
catch (Exception e) {
// TODO: handle exception
}
finally{
lock.unlock();
}
} public void print2()
{
lock.lock();
try{
while(printnext!=2)
{
condition.await();
}
System.out.print(2);
printnext=3;
condition.signalAll();
}
catch (Exception e) {
}
finally{
lock.unlock();
}
} public void print3()
{
lock.lock();
try{
while(printnext!=3)
{
condition.await();
}
System.out.print(3);
printnext=1;
condition.signalAll();
}
catch (Exception e) {
// TODO: handle exception
}
finally{
lock.unlock();
}
} public static void main(String[] args) {
PrintByOrder order=new PrintByOrder();
Runnable runnable1=new Runnable() { @Override
public void run() {
while(true){
order.print1();
}
}
}; Runnable runnable2=new Runnable() { @Override
public void run() {
while(true){
order.print2();
}
}
}; Runnable runnable3=new Runnable() { @Override
public void run() {
while(true){
order.print3();
}
}
}; new Thread(runnable1).start();
new Thread(runnable2).start();
new Thread(runnable3).start();
}
}

读写锁,比上面的lock+condition提高效率。

ReentrantReadWriteLock会使用两把锁来解决问题,一个读锁,一个写锁
线程进入读锁的前提条件:
    没有其他线程的写锁,
    没有写请求或者有写请求,但调用线程和持有锁的线程是同一个

线程进入写锁的前提条件:
    没有其他线程的读锁
    没有其他线程的写锁

简单来说,就是读读共享,写写互斥,读写互斥。

另外,ReentrantReadWriteLock.readLock 无需newCondition,而ReentrantReadWriteLock.writeLock可以newCondition,用于多个读线程之间的通信。

 import java.util.concurrent.locks.ReentrantReadWriteLock;

 public class ReadWriteLock {
private ReentrantReadWriteLock rw= new ReentrantReadWriteLock(); public void readLock(){ try {
rw.readLock().lock();
System.out.println("read before sleep:"+Thread.currentThread().getName()+":"+System.currentTimeMillis());
Thread.sleep(2000);
System.out.println("read after sleep:"+Thread.currentThread().getName()+":"+System.currentTimeMillis());
} catch (Exception e) {
// TODO: handle exception
}finally{
rw.readLock().unlock();
}
} public void writeLock(){ try {
rw.writeLock().lock();
System.out.println("write before sleep:"+Thread.currentThread().getName()+":"+System.currentTimeMillis());
Thread.sleep(2000);
System.out.println("write after sleep:"+Thread.currentThread().getName()+":"+System.currentTimeMillis());
} catch (Exception e) {
// TODO: handle exception
}finally{
rw.writeLock().unlock();
}
} public static void main(String[] args) {
ReadWriteLock rwl=new ReadWriteLock();
Runnable runnable=new Runnable() { @Override
public void run() {
rwl.writeLock();
rwl.readLock(); }
};
Thread[] threads=new Thread[10];
for(int i=0;i<5;i++)
{
threads[i]=new Thread(runnable);
}
for(int i=0;i<5;i++)
{
threads[i].start();
}
} }

lock+Condition的更多相关文章

  1. 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, ...

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

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

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

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

  4. Lock+Condition实现机制

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

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

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

  6. JDK1.5中LOCK,Condition的使用

    import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.uti ...

  7. Java多线程——Lock&Condition

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

  8. Java Lock & Condition

    /* jdk1.5以后将同步和锁封装成了对象. 并将操作锁的隐式方式定义到了该对象中, 将隐式动作变成了显示动作. Lock接口: 出现替代了同步代码块或者同步函数.将同步的隐式锁操作变成现实锁操作. ...

  9. Java多线程技术-Lock/Condition

    在java1.5中Lock对象来实现同步的效果,而且使用上更方便. 使用ReentrantLock实现同步 public class MyService { private Lock lock = n ...

随机推荐

  1. Gradle Goodness: Set Java Compiler Encoding

    If we want to set an explicit encoding for the Java compiler in Gradle we can use the options.encodi ...

  2. 工具 | Axure基础操作 No.2

    不废话了,直接如之前一样上操作图才是正道. 1.设置文本类型为密码或者文件类型 可以在属性中也选择最大长度制定长度. 如果设置类型为文件,在浏览器中就会自动变成选择本地文件的按钮. 2.文本框提示文字 ...

  3. js的垃圾回收机制

    Js具有自动垃圾回收机制.垃圾收集器会按照固定的时间间隔周期性的执行. JS中最常见的垃圾回收方式是标记清除. 工作原理:是当变量进入环境时,将这个变量标记为“进入环境”.当变量离开环境时,则将其标记 ...

  4. 557. Reverse Words in a String III (5月25日)

    解答 class Solution { public: string reverseWords(string s) { string temp,result; while(1){ if(s.find( ...

  5. CentOS7 yum命令

    1.yum 清理缓存 [hado@localhost /]# yum clean all [hado@localhost /]# rm -rf /var/cache/yum/*

  6. 解决微信小程序安卓手机访问不到图片,无法显示图片

    关于微信小程序不显示图片 通病可能有以下几个可能性: 非本地图片:确定图片资源存在,copy 图片url再浏览器打开,确定图片资源存在且能正常访问 本地图片:确定相对路径或者绝对路径正确 微信小程序图 ...

  7. MPP调研

    一.MMP数据库 MPP是massively parallel processing,一般指使用多个SQL数据库节点搭建的数据仓库系统.执行查询的时候,查询可以分散到多个SQL数据库节点上执行,然后汇 ...

  8. opencv3 学习一 - Visual Studio 配置

    Step 1 下载最新版的Opencv3.4.2,见图片中的网址,选择 Win Pack. Step 2 安装Opencv3 到指定目录,见图片,路径后面会用到. Step 3 把安装目录下的bin路 ...

  9. Python学习1——关于变量

    在python中,使用变量之前不需要声明变量的数据类型, 但是,使用变量前,必须要先对变量进行赋值: 例: num01 += 100 print('num01') 上述例子中,表示的意思是 num01 ...

  10. Java学习笔记二十一:Java面向对象的三大特性之继承

    Java面向对象的三大特性之继承 一:继承的概念: 继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类. 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方 ...