lock+Condition
关键字 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的更多相关文章
- 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, ...
- 生产者消费者两种实现:wait/notifyAll和Lock/Condition
1.wait/notifyAll /** * 面试题:写一个固定容量同步容器,拥有put和get方法,以及getCount方法, * 能够支持2个生产者线程以及10个消费者线程的阻塞调用 * * 使用 ...
- 玩转Java多线程(Lock.Condition的正确使用姿势)
转载请标明博客的地址 本人博客和github账号,如果对你有帮助请在本人github项目AioSocket上点个star,激励作者对社区贡献 个人博客:https://www.cnblogs.com/ ...
- Lock+Condition实现机制
前言:大部分多线程同步场景,在功能和性能层面,synchronized可以满足,少部分场景Lock可以满足,dubbo的源码也符合这个比例,需要使用到Condition的场景极少,整个dubbo源码中 ...
- 【java并发编程】Lock & Condition 协调同步生产消费
一.协调生产/消费的需求 本文内容主要想向大家介绍一下Lock结合Condition的使用方法,为了更好的理解Lock锁与Condition锁信号,我们来手写一个ArrayBlockingQueue. ...
- JDK1.5中LOCK,Condition的使用
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.uti ...
- Java多线程——Lock&Condition
Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象.两个线程执行的代码片段要实现同步互斥的效果,它们必须用同一个Lock对象. package ...
- Java Lock & Condition
/* jdk1.5以后将同步和锁封装成了对象. 并将操作锁的隐式方式定义到了该对象中, 将隐式动作变成了显示动作. Lock接口: 出现替代了同步代码块或者同步函数.将同步的隐式锁操作变成现实锁操作. ...
- Java多线程技术-Lock/Condition
在java1.5中Lock对象来实现同步的效果,而且使用上更方便. 使用ReentrantLock实现同步 public class MyService { private Lock lock = n ...
随机推荐
- uiwebview与objective-c
利用oc调用js很简单, 系统直接提供了方法stringByEvaluatingJavaScriptFromString [webView stringByEvaluatingJavaScriptFr ...
- java web中对json的使用
一.在Java Web的开发过程中,如果希望调用Java对象转化成JSON对象等操作.则需要引入以下jar包,不然运行时则报错. 1.commons-beanutils.jar 2.commons-c ...
- pt-online-schema-change在线修改表结构
工具简介 pt-osc模仿MySQL内部的改表方式进行改表,但整个改表过程是通过对原始表的拷贝来完成的,即在改表过程中原始表不会被锁定,并不影响对该表的读写操作.首先,osc创建与原始表相同的不包含数 ...
- CentOS7 LNMP+phpmyadmin环境搭建(三、安装phpmyadmin)
之前我们已经安装了lnmp的环境,现在让我们来安装phpmyadmin. 跟前一样,yum默认的库里是没有phpmyadmin的,我们需要从epel库里进行安装,之前已经安装过epel的朋友就可以直接 ...
- xp sp3安装.Net 4.0提示严重错误,0x80070643,解决办法2017版
客户电脑上要装金税开票软件,需要.net 4.0.30319.1,电脑环境是xp sp3,已经安装了.net 2, .net 3.5sp1,安装.net 4.0的时候提示错误0x80070643 因为 ...
- vmware 虚拟机设置 redhat 桥接模式
1.设置 vmware 网络模式 2.设置 linux 网络模式
- python 两个面试题
1.下面程序的运算结果是什么?? class Parent: def func(self): print("In Parent func") def __init__(self): ...
- 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 ...
- [BZOJ4552][Tjoi2016&Heoi2016]排序(二分答案+线段树)
二分答案mid,将>=mid的设为1,<mid的设为0,这样排序就变成了区间修改的操作,维护一下区间和即可 然后询问第q个位置的值,为1说明>=mid,以上 时间复杂度O(nlog2 ...
- [bzoj5278][Usaco2018 Open]Out of Sorts
有点厉害,,,不会啊 答案就是所有前i个数有多少不在前i个里的max? 为啥啊求助