import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ReetlockABC { public static void main(String[] args) {
// TODO Auto-generated method stub
final Out out = new Out();
new Thread(new Runnable() {@Override
public void run() {
// TODO Auto-generated method stub
try {
out.pB();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {@Override
public void run() {
// TODO Auto-generated method stub
try {
out.pA();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {@Override
public void run() {
// TODO Auto-generated method stub
try {
out.pC();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}}class Out {
Lock lock = new ReentrantLock();
Condition a_b = lock.newCondition();
//可以理解为等待a唤醒b
Condition b_c = lock.newCondition();
Condition c_a = lock.newCondition();
int flag = 1;
public void pA() throws InterruptedException {
while (true) {
lock.lock();
while (flag != 1)
c_a.await();
System.out.println("a");
flag = 2;
a_b.signal();
lock.unlock();
}
} public void pB() throws InterruptedException {
while (true) {
lock.lock();
while (flag != 2)
a_b.await();
System.out.println("b");
flag = 3;
b_c.signal();
lock.unlock();
}
} public void pC() throws InterruptedException {
while (true) {
lock.lock();
while (flag != 3)
b_c.await();
System.out.println("c");
flag = 1;
c_a.signal();
lock.unlock();
}
}
}
以前我用synchronized同步块时,当有三个或以上的线程时必须用obj.signalAll(); (obj.signal()可能会唤醒错人导致死锁或者用嵌套的synchronized(麻烦死了而且容易死锁)),用lock的Condition可以唤醒指定对象,不用唤醒全部
推荐阅读
- 代码狂魔|实战证明java中的两把锁ReentrantLock与synchronized的系统调用
- 进程通信方式
- 解决方案|大文件拆分方案的java实践
- 多线程编程(1)(共享内存与锁)
- Java|多线程编程(二)——面试题,每个线程只打印一种字符,多个线程协同顺序打印n次字符串(求大神的其他实现方案)
- 一道面试题(多个线程按顺序输出)
- 多线程|java多线程实现奇偶数输出
- 面试题--三个线程循环打印ABC 10次(另类解决方法)
- 用信号量(互斥锁)实现两个线程交替打印