基于JOIN
線程自己的邏輯與控制邏輯分離诀紊,執(zhí)行邏輯不受影響巍杈,耦合性最低
Thread t1 = new Thread(new T1());
t1.start();
t1.join();
Thread t2 = new Thread(new T2());
t2.start();
t2.join();
Thread t3 = new Thread(new T3());
t3.start();
t3.join();
基于信號(hào)量
每個(gè)線程需要知道自己運(yùn)行所需要的信號(hào)量闺金,以及開(kāi)啟下一個(gè)線程的信號(hào)量拒课,
有點(diǎn)像 chain 模式狼牺。 執(zhí)行邏輯和控制邏輯有耦合羡儿。
public static void main(String[] args) throws Exception {
Semaphore lock1 = new Semaphore(1);
Semaphore lock2 = new Semaphore(1);
Semaphore lock3 = new Semaphore(1);
lock2.acquire();
lock3.acquire();
for(int i =0; i < 10; i++) {
Thread t1 = new Thread(new T1(lock1,lock2));
Thread t2 = new Thread(new T2(lock2, lock3));
t2.start();
Thread t3 = new Thread(new T3(lock3, lock1));
t3.start();
t1.start();
}
}
static class T1 implements Runnable{
public Semaphore nextLock;
Semaphore current;
public T1(Semaphore current, Semaphore nextlock){
this.nextLock=nextlock;
this.current =current;
}
@Override
public void run() {
try {
current.acquire();
System.out.println("Sleep");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("I am T-111");
nextLock.release();
}
}
static class T2 implements Runnable{
public Semaphore nextLock;
Semaphore current;
public T2(Semaphore current, Semaphore nextlock){
this.nextLock=nextlock;
this.current =current;
}
@Override
public void run() {
try {
current.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("I am T-222");
nextLock.release();
}
}
static class T3 implements Runnable{
public Semaphore nextLock;
Semaphore current;
public T3(Semaphore current, Semaphore nextlock){
this.nextLock=nextlock;
this.current =current;
}
@Override
public void run() {
try {
current.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("I am T-333");
nextLock.release();
}
}
基于countDownlatch
和信號(hào)量的思路是一樣的,每個(gè)線程需要等待自己 latch是钥,并且完成任務(wù)之后掠归,對(duì)下一個(gè)latch 進(jìn)行 countDown缅叠。
public static void main(String[] args) throws Exception {
for(int i =0; i < 1; i++) {
CountDownLatch c1 = new CountDownLatch(1);
CountDownLatch c2 = new CountDownLatch(1);
Thread t1 = new Thread(new T1(c1));
Thread t2 = new Thread(new T2(c1,c2));
t2.start();
Thread t3 = new Thread(new T3(c2));
t3.start();
t1.start();
}
}
static class T1 implements Runnable{
public CountDownLatch c1;
public T1(CountDownLatch c1){
this.c1=c1;
}
@Override
public void run() {
try {
System.out.println("Sleep");
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("I am T-111");
c1.countDown();
}
}
static class T2 implements Runnable{
public CountDownLatch c1;
CountDownLatch c2;
public T2(CountDownLatch c1, CountDownLatch c2){
this.c1=c1;
this.c2 =c2;
}
@Override
public void run() {
try {
c1.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("I am T-222");
c2.countDown();
}
}
static class T3 implements Runnable{
CountDownLatch c2;
public T3(CountDownLatch c2){
this.c2 =c2;
}
@Override
public void run() {
try {
c2.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("I am T-333");
}
}
基于條件變量
條件變量是lock+ condition, 是最接近用 notify+wait 來(lái)實(shí)現(xiàn)的方式虏冻。
每個(gè)lock 可以穿件多個(gè)條件變量肤粱, 每個(gè) 條件變量 await 都能夠釋放lock。
但是condition 的singal 方法可以精確的喚醒等待的線程厨相。這是條件變量現(xiàn)對(duì)于notify的優(yōu)勢(shì)领曼,可以更加精準(zhǔn)的控制。
public static void main(String[] args) throws Exception {
Lock lock = new ReentrantLock();
Condition condition1 = lock.newCondition();
Condition condition2 = lock.newCondition();
Thread t1 = new Thread(new T1(lock, condition1));
Thread t2 = new Thread(new T2(lock, condition1,condition2));
t2.start();
Thread t3 = new Thread(new T3(lock, condition2,null));
t3.start();
t1.start();
}
static class T1 implements Runnable{
public Lock lock;
Condition nextCondition;
public T1(Lock lock, Condition nextCondition){
this.lock = lock;
this.nextCondition =nextCondition;
}
@Override
public void run() {
try {
lock.lock();
System.out.println("Sleep");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("I am T-111");
nextCondition.signal();
lock.unlock();
}
}
static class T2 implements Runnable{
public Lock lock;
Condition nextCondition;
Condition currentCondition;
public T2(Lock lock, Condition currentCondition,Condition nextCondition){
this.lock = lock;
this.nextCondition =nextCondition;
this.currentCondition = currentCondition;
}
@Override
public void run() {
lock.lock();
try {
currentCondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("I am T-222");
nextCondition.signal();
lock.unlock();
}
}
static class T3 implements Runnable{
public Lock lock;
Condition nextCondition;
Condition currentCondition;
public T3(Lock lock, Condition currentCondition,Condition nextCondition){
this.lock = lock;
this.nextCondition =nextCondition;
this.currentCondition = currentCondition;
}
@Override
public void run() {
lock.lock();
try {
currentCondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("I am T-333");
lock.unlock();
}
}