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 ...
随机推荐
- kafka 参数配置 1
kafka 参数配置 #参数配置 * broker.id : kafka 集群的唯一,标识每个broker * log.dirs : 指定kafka持久化消息的目录,可以设置多个目录,如:/home/ ...
- 提示AttributeError: 'module' object has no attribute 'HTTPSHandler'解决方法
今天在新机器上安装sqlmap,运行提示AttributeError: 'module' object has no attribute 'HTTPSHandler' 网上找了找资料,发现一篇文章ht ...
- .net core运行环境搭建 linux + windows
---------------------------------------linux------------------------------------------------- 一.添加do ...
- 系统优化怎么做-Linux系统配置优化
大家好,这里是「聊聊系统优化 」,并在下列地址同步更新 博客园:http://www.cnblogs.com/changsong/ 知乎专栏:https://zhuanlan.zhihu.com/yo ...
- lable随堂笔记
lable标签与属性 lable标签:for属性,让标签与指定的input元素建立标签:将input元素包含在lable标签中. <table border="2" alig ...
- Oracle创建聚簇表
创建聚簇表过程: 创建簇(cluster)----创建簇表(基本类似创建一般表但有区别)----创建簇索引(index)----数据管理 创建簇: create cluster stu_ach(sid ...
- iOS原生混合RN开发最佳实践
iOS原生混合RN开发详解 做过原生iOS开发或者Android开发的同学们肯定也都了解Hybrid,有一些Hybrid的开发经验,目前我们企业开发中运用最广泛的Hybrid App技术就是原生与H5 ...
- CSS、JavaScript学习过程
初学JavaScript,通过博客记录自己学习过程中遇到的问题.(包含少量CSS) 零碎记录 JavaScript 输出 type="text/javascript" 那些老旧的实 ...
- activemq整合springboot使用(个人微信小程序用)
1.引入依赖 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spri ...
- svn出现目标计算机积极拒绝无法链接
这是由于没有启动服务器端监控的原因,只需要执行以下代码即可 svnserve -d --listen-port 8000 -r /opt/svn