廢話不說了,晚上看到一個問題,需要ABC線程,能依次打印ABC(需要循環的)?
之前看能沒有看到它需要循環打出這些,只是覺得他要順序打出,所以就用了join 這個關鍵字做了一個demo;
package com.zeng.thread;
/**
* 實現三個線程ABC,按照順序輸出ABC
* 方案一
*
* @author leo-zeng
*
*/
public class Test1 {
public static void main(String[] args) throws Exception {
//A 線程
Thread t1 = new Thread(new Runnable() {
public void run() {
System.out.println("A");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"A");
//b線程
Thread t2 = new Thread(new Runnable() {
public void run() {
System.out.println("B");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "B");
//C 線程
Thread t3 = new Thread(new Runnable() {
public void run() {
System.out.println("C");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"C");
t1.start();
t1.join();
t2.start();
t2.join();
t3.start();
}
}
打印出的結果是ABC
後來仔細一看,不滿足,問題的條件是需要循環打出ABC,所以用join 是不滿足的,這會只能用到lock,通過condition來滿足這個需求;下面也寫了這個demo,
demo比較簡單,通過一個reentrantLock 和 condition 的await 和single 方法,進行線程間的輪詢,來達到結果;看下demo吧!
package com.zeng.thread;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
* Abc 三個線程分別輸出循環輸出 abc 用reentrantLock
*
* @author leo-zeng
*
*/
public class ReentrantLockDemo {
public static void main(String[] args) {
// 重入鎖
final ReentrantLock rLock = new ReentrantLock();
// 三個condition
final Condition aCon = rLock.newCondition();
final Condition bCon = rLock.newCondition();
final Condition cCon = rLock.newCondition();
//線程a
Thread a = new Thread(new Runnable() {
public void run() {
try {
//先給第一個線程加上一段時間,給bc 線程 加鎖 ,加信號
Thread.sleep(500);
} catch (InterruptedException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
for (int i = 0; i < 3; i++) {
try {
// 加上鎖
rLock.lock();
System.out.println("A");
Thread.sleep(1000);
// 打印完A 之後 關閉a 給b 信號
bCon.signal();
//等待一個a給的信號
try {
aCon.await();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 解鎖
rLock.unlock();
}
}
}
}, "A");
//線程b
Thread b = new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 3; i++) {
try {
// 加上鎖
rLock.lock();
try {
//等待bcon
bCon.await();
} catch (InterruptedException e2) {
e2.printStackTrace();
}
System.out.println("B");
Thread.sleep(1000);
// 打印完b 之後 給c 信號
cCon.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 解鎖
rLock.unlock();
}
}
}
}, "B");
//線程c
Thread c = new Thread(new Runnable() {
public void run() {
for (int i = 0; i <3; i++) {
try {
// 加上鎖
rLock.lock();
try {
//等待ccon
cCon.await();
} catch (InterruptedException e2) {
e2.printStackTrace();
}
System.out.println("C");
Thread.sleep(1000);
// 打印完c 之後 給a 信號
aCon.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 解鎖
rLock.unlock();
}
}
}
}, "C");
//a b c 線程
a.start();
b.start();
c.start();
Thread.yield();
}
}
這裏就不重點介紹ReentrantLock鎖了;下次再和synchronized 一起對比介紹!