與Runntable相似,只多了返回值,並且拋出了異常。
生產者消費者案例:
public class TestABCAlternate {
public static void main(String[] args) {
ABCAlternate abc = new ABCAlternate();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
abc.loopA(i);
}
}
}, "A").start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
abc.loopB(i);
}
}
}, "B").start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
abc.loopC(i);
}
System.out.println("-----------------");
}
}, "C").start();
}
}
class ABCAlternate{
private static int number = 1; //標記,執行A,B,C
Lock lock = new ReentrantLock();
Condition condition1 = lock.newCondition();
Condition condition2 = lock.newCondition();
Condition condition3 = lock.newCondition();
public void loopA(int totalLoop){
lock.lock(); //加鎖
try {
if(number != 1){
condition1.await();
}
for (int i = 0; i < 2; i++) {
System.out.println(Thread.currentThread().getName() + "\t" + totalLoop + "\t" + i);
}
number = 2;
condition2.signal(); //喚醒下一個
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock(); //釋放鎖
}
}
public void loopB(int totalLoop){
lock.lock(); //加鎖
try {
if(number != 2){
condition2.await();
}
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + "\t" + totalLoop + "\t" + i);
}
number = 3;
condition3.signal(); //喚醒下一個
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock(); //釋放鎖
}
}
public void loopC(int totalLoop){
lock.lock(); //加鎖
try {
if(number != 3){
condition3.await();
}
for (int i = 0; i < 4; i++) {
System.out.println(Thread.currentThread().getName() + "\t" + totalLoop + "\t" + i);
}
number = 1;
condition1.signal(); //喚醒下一個
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock(); //釋放鎖
}
}
}