代碼都已上傳github
P02 使用三個(gè)線程使得ABC 循環(huán)輸出十次
心得
- 利用Condition 來(lái)控制對(duì)哪個(gè)類(lèi)型的鎖進(jìn)行釋放醇蝴。可以達(dá)到對(duì)3個(gè)線程的一個(gè)控制导坟。
- 對(duì)于線程輸出的控制順序缠诅,可以加入一個(gè)判斷順序Int.來(lái)決定是否輪到該線程運(yùn)行,不是則繼續(xù)等待乍迄。
代碼塊
public class P02 {
private static ReentrantLock lock;
public static int ThSum=1; //決定那個(gè)線程運(yùn)行
/*使用三個(gè)線程使得ABC 循環(huán)輸出十次*/
public static void po2(){
lock = new ReentrantLock(true);
Thread t1 = new Thread(new t1(lock));
Thread t2 = new Thread(new t2(lock));
Thread t3 = new Thread(new t3(lock));
t1.start();
t2.start();
t3.start();
}
}
class t1 implements Runnable{
private ReentrantLock lock;
public static Condition conditionA;
public t1(ReentrantLock lock) {
this.lock = lock;
conditionA = lock.newCondition();
}
@Override
public void run() {
try {
for (int i = 1; i <= 10; i++) {
lock.lock();
while (P02.ThSum != 1) { //如果沒(méi)有該判斷順序管引,則線程1 可能會(huì)再次獲得鎖。不能確保順序正確
conditionA.await(); //當(dāng)還不是該線程輸出的時(shí)候闯两,釋放鎖
}
System.out.print("第"+i+"次");
System.out.print('A');
P02.ThSum = 2;
t2.conditionB.signalAll(); //釋放第二個(gè)線程 喚醒第二個(gè)線程
lock.unlock(); //釋放鎖褥伴,是因?yàn)樽詈笠淮蔚臅r(shí)候谅将,如果沒(méi)有釋放鎖,那么2 3 線程并不能獲取到鎖重慢。
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class t2 implements Runnable{
private ReentrantLock lock;
public static Condition conditionB;
public t2(ReentrantLock lock) {
this.lock = lock;
conditionB = lock.newCondition();
}
@Override
public void run() {
try {
for (int i = 0; i < 10; i++) {
lock.lock();
while (P02.ThSum != 2) {
conditionB.await();
}
System.out.print('B');
P02.ThSum = 3;
t3.conditionC.signalAll();
lock.unlock();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class t3 implements Runnable{
private ReentrantLock lock;
public static Condition conditionC;
public t3(ReentrantLock lock) {
this.lock = lock;
conditionC = lock.newCondition();
}
@Override
public void run() {
try {
for (int i = 0; i < 10; i++) {
lock.lock();
while (P02.ThSum != 3) {
conditionC.await();
}
System.out.println('C');
P02.ThSum = 1;
t1.conditionA.signalAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
輸出效果
image.png