关键字 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. uiwebview与objective-c

    利用oc调用js很简单, 系统直接提供了方法stringByEvaluatingJavaScriptFromString [webView stringByEvaluatingJavaScriptFr ...

  2. java web中对json的使用

    一.在Java Web的开发过程中,如果希望调用Java对象转化成JSON对象等操作.则需要引入以下jar包,不然运行时则报错. 1.commons-beanutils.jar 2.commons-c ...

  3. pt-online-schema-change在线修改表结构

    工具简介 pt-osc模仿MySQL内部的改表方式进行改表,但整个改表过程是通过对原始表的拷贝来完成的,即在改表过程中原始表不会被锁定,并不影响对该表的读写操作.首先,osc创建与原始表相同的不包含数 ...

  4. CentOS7 LNMP+phpmyadmin环境搭建(三、安装phpmyadmin)

    之前我们已经安装了lnmp的环境,现在让我们来安装phpmyadmin. 跟前一样,yum默认的库里是没有phpmyadmin的,我们需要从epel库里进行安装,之前已经安装过epel的朋友就可以直接 ...

  5. xp sp3安装.Net 4.0提示严重错误,0x80070643,解决办法2017版

    客户电脑上要装金税开票软件,需要.net 4.0.30319.1,电脑环境是xp sp3,已经安装了.net 2, .net 3.5sp1,安装.net 4.0的时候提示错误0x80070643 因为 ...

  6. vmware 虚拟机设置 redhat 桥接模式

    1.设置 vmware 网络模式 2.设置 linux 网络模式

  7. python 两个面试题

    1.下面程序的运算结果是什么?? class Parent: def func(self): print("In Parent func") def __init__(self): ...

  8. ACM1002:A + B Problem II

    Problem Description I have a very simple problem for you. Given two integers A and B, your job is to ...

  9. [BZOJ4552][Tjoi2016&Heoi2016]排序(二分答案+线段树)

    二分答案mid,将>=mid的设为1,<mid的设为0,这样排序就变成了区间修改的操作,维护一下区间和即可 然后询问第q个位置的值,为1说明>=mid,以上 时间复杂度O(nlog2 ...

  10. [bzoj5278][Usaco2018 Open]Out of Sorts

    有点厉害,,,不会啊 答案就是所有前i个数有多少不在前i个里的max? 为啥啊求助