0
点赞
收藏
分享

微信扫一扫

聊聊Condition


本文可作为传智播客《张孝祥-Java多线程与并发库高级应用》的学习笔记。


上面我们说了Lock,那是对synchronized的一种更为面向对象的替代,在原来的synchronized内部,我们可以调用object的wait与notify方法,那么使用lock之后,如何进行线程的通信呢。

对锁不清楚的朋友可以看看




答案是condition。


condition一方面是对lock功能的补充(也就是说,你用了lock,为了保证线程的通信,就得用condition)


另一方面,synchronized的notifyall是唤醒所有等待的线程,那么如果有些线程我不想唤醒呢。


看下面这个例子


主线程运行10次,然后子线程2运行20次,接着子线程3运行30次


上面的整体运行4次。


我们分析一下,主线程运行10次之后,下面一方面让自己阻塞,同时应该唤醒子线程2,并且不能唤醒子线程3。


如果用notifyAll就等于把线程2与线程3都唤醒了。



我们在这里说明一下 

Reentrantlock相比较于synchronized还少有三个优势

1 等待可中断  具体的例子参考  http://uule.iteye.com/blog/1488356

2 实现公平锁 就是线程a在操作某个对象,线程b,c,d后面又依次来了,如果是非公平锁,那么等a结束后,bcd接手的概率是一样的,如果是公平锁那么a完了之后就是b
    synchronized是非公平的是,Reentrantlock默认情况下也是非公平的,但可以通过有带Boolean只的构造函数构建一个公平锁
3 绑定多个条件 也就是下面讲的
4  有三种使用方式
    a)  lock(), 如果获取了锁立即返回,如果别的线程持有锁,当前线程则一直处于休眠状态,直到获取锁
    b) tryLock(), 如果获取了锁立即返回true,如果别的线程正持有锁,立即返回false;
    c)tryLock(long timeout,TimeUnit unit),   如果获取了锁定立即返回true,如果别的线程正持有锁,会等待参数给定的时间,在等待的过程中,如果获取了锁定,就返回true,如果等待超时,返回false; 
参考资料 ​​​http://houlinyan.iteye.com/blog/1112535​​


另外我得说明一点

就性能来说,在java6之后,reentrantlock与synchronized已经差不多了

而且Reentrantlock得主动释放

所有到底选择哪个实现互斥,大家还是得考虑一下

    







看看方法


聊聊Condition_子线程





常用的就是await与signal。


这个两个就刚好对应object的wait与notify。




我们看代码:


package cn.itcast.heima2;


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


public class ThreeConditionCommunication {


/**
* @param args
*/
public static void main(String[] args) {

final Business business = new Business();
new Thread(
new Runnable() {

@Override
public void run() {

for(int i=1;i<=4;i++){
business.sub2(i);
}

}
}
).start();

new Thread(
new Runnable() {

@Override
public void run() {

for(int i=1;i<=4;i++){
business.sub3(i);
}

}
}
).start();

for(int i=1;i<=4;i++){
business.main(i);
}

}


static class Business {
Lock lock = new ReentrantLock();
Condition condition1 = lock.newCondition();
Condition condition2 = lock.newCondition();
Condition condition3 = lock.newCondition();
private int shouldSub = 1;
public void sub2(int i){
lock.lock();
try{
while(shouldSub != 2){
try {
condition2.await();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
for(int j=1;j<=20;j++){
System.out.println("sub2 thread sequence of " + j + ",loop of " + i);
}
shouldSub = 3;
condition3.signal();
}finally{
lock.unlock();
}
}


public void sub3(int i){
lock.lock();
try{
while(shouldSub != 3){
try {
condition3.await();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
for(int j=1;j<=30;j++){
System.out.println("sub3 thread sequence of " + j + ",loop of " + i);
}
shouldSub = 1;
condition1.signal();
}finally{
lock.unlock();
}
}

public void main(int i){
lock.lock();
try{
while(shouldSub != 1){
try {
condition1.await();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
for(int j=1;j<=10;j++){
System.out.println("main thread sequence of " + j + ",loop of " + i);
}
shouldSub = 2;
condition2.signal();
}finally{
lock.unlock();
}
}

}
}


举报

相关推荐

0 条评论