假設我要讓3個線程按照順序打印ABC,那麼可使用Join,若是要求多線程按順序循環打印,則不能用join了java
join是Thread類的一個方法,啓動線程後直接調用。在不少狀況下,主線程生成並起動了子線程,若是子線程裏要進行大量的耗時的運算,主線程每每將於子線程以前結束,可是若是主線程處理完其餘的事務後,須要用到子線程的處理結果,也就是主線程須要等待子線程執行完成以後再結束,這個時候就要用到join()方法了。git
join()的做用是:「等待該線程終止」,這裏須要理解的就是該線程是指的主線程等待子線程的終止。也就是在子線程調用了join()方法後面的代碼,只有等到子線程結束了才能執行。github
具體代碼:多線程
package googleTest; public class ThreadTest { public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(new Runner("A")); Thread t2 = new Thread(new Runner("B")); Thread t3 = new Thread(new Runner("C")); t1.start(); t1.join(); t2.start(); t2.join(); t3.start(); t3.join(); } } class Runner implements Runnable{ public String name; Runner(String name) { this.name=name; } @Override public void run() { System.out.println(name+""); } }
</pre>lock時注意unlock就能夠啦</p><p class="p1"><pre name="code" class="java">import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class ThreadTest3 { private static Lock lock=new ReentrantLock(); private static int state = 0; static class ThreadA extends Thread { @Override public void run() { lock.lock(); if (state % 3 == 0) { System.out.println("A"); state++; } lock.unlock(); } } static class ThreadB extends Thread { @Override public void run() { lock.lock(); if (state % 3 == 1) { System.out.println("B"); state++; } lock.unlock(); } } static class ThreadC extends Thread { @Override public void run() { lock.lock(); if (state % 3 == 2) { System.out.println("C"); state++; } lock.unlock(); } } public static void main(String[] args) { new ThreadA().start(); new ThreadB().start(); new ThreadC().start(); } }
就拿生產者消費者模式來講,當倉庫滿了的時候,又再執行到 生產者 線程的時候,會把 該 生產者 線程進行阻塞,再喚起一個線程.併發
可是此時喚醒的是消費者線程仍是生產者線程,是未知的。若是再次喚醒的仍是生產者線程,那麼還須要把它進行阻塞,再喚起一個線程,再此循環,直到喚起的是消費者線程。這樣就可能存在 時間或者資源上的浪費,ide
因此說 有了Condition 這個東西。Condition 用 await() 代替了 Object 的 wait() 方法,用 signal() 方法代替 notify() 方法。注意:Condition 是被綁定到 Lock 中,要建立一個 Lock 的 Condition 必須用 newCondition() 方法。ui
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class ThreadTest2 { private static Lock lock = new ReentrantLock(); private static int count = 0; private static Condition A = lock.newCondition(); private static Condition B = lock.newCondition(); private static Condition C = lock.newCondition(); static class ThreadA extends Thread { @Override public void run() { lock.lock(); try { for (int i = 0; i < 10; i++) { while (count % 3 != 0) A.await(); // 會釋放lock鎖 System.out.print("A"); count++; B.signal(); // 喚醒相應線程 } } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } } static class ThreadB extends Thread { @Override public void run() { lock.lock(); try { for (int i = 0; i < 10; i++) { while (count % 3 != 1) B.await(); System.out.print("B"); count++; C.signal(); } } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } } static class ThreadC extends Thread { @Override public void run() { lock.lock(); try { for (int i = 0; i < 10; i++) { while (count % 3 != 2) C.await(); System.out.println("C"); count++; A.signal(); } } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } } public static void main(String[] args) throws InterruptedException { new ThreadA().start(); new ThreadB().start(); ThreadC threadC = new ThreadC(); threadC.start(); threadC.join(); System.out.println(count); } }
Semaphore爲併發包中提供用於控制某資源同時能夠被幾個線程訪問的類。通常用於限制線程訪問的資源個數。也可用於線程間的信號傳遞。this
import java.util.concurrent.Semaphore; public class ThreadTest4 { private static Semaphore A = new Semaphore(1); private static Semaphore B = new Semaphore(1); private static Semaphore C = new Semaphore(1); static class ThreadA extends Thread { @Override public void run() { try { for (int i = 0; i < 10; i++) { A.acquire(); System.out.print("A"); B.release(); } } catch (InterruptedException e) { e.printStackTrace(); } } } static class ThreadB extends Thread { @Override public void run() { try { for (int i = 0; i < 10; i++) { B.acquire(); System.out.print("B"); C.release(); } } catch (InterruptedException e) { e.printStackTrace(); } } } static class ThreadC extends Thread { @Override public void run() { try { for (int i = 0; i < 10; i++) { C.acquire(); System.out.println("C"); A.release(); } } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) throws InterruptedException { B.acquire(); C.acquire(); // 開始只有A能夠獲取, BC都不能夠獲取, 保證了A最早執行 new ThreadA().start(); new ThreadB().start(); new ThreadC().start(); } }