實用多線程類
這些類都是位於java.concurrent.util.*包下。
CountDownLatch
常用於監聽某些初始化操作,等待初始化這些完畢,通知主線程繼續工作。針對的是一個線程,一個線程等待,其他線程通知。
public class U01CountDownLatch { public static void main(String[] args) {
//代表countDown方法調用的次數,只有調用次數達到了阻塞的線程纔會開始執行 CountDownLatch countDownLatch = new CountDownLatch(2);
//案例:某應用,啓動之前要加載A配置文件、B配置文件 new Thread(new Runnable() { @Override public void run() { System.out.println("=== t1 開始啓動"); try { //開始await countDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("=== t1 啓動完成"); } },"t1").start();
new Thread(new Runnable() { @Override public void run() { System.out.println("開始加載配置文件t2"); //第一次countDown countDownLatch.countDown(); System.out.println("加載配置文件t2完成"); } },"t2").start();
new Thread(new Runnable() { @Override public void run() { System.out.println("開始加載配置文件t3"); //第二次countDown countDownLatch.countDown(); System.out.println("加載配置文件t3完成"); } },"t3").start();
} } |
CyclicBarrier
假設每個線程代表一個跑步運動員,當運動員都準備好後,才一起出發,只要有一個人沒有準備好,所有人都要等待。針對的是多個線程,多個線程完成才完成。
public class U02CyclicBarrier { public static void main(String[] args) { //指定運動員數量 CyclicBarrier cyclicBarrier = new CyclicBarrier(2);
ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(2); newFixedThreadPool.submit(new Athlete("A",cyclicBarrier)); newFixedThreadPool.submit(new Athlete("B",cyclicBarrier)); // newFixedThreadPool.submit(new Athlete("C",cyclicBarrier)); newFixedThreadPool.shutdown(); } } class Athlete implements Runnable {
private String name;
private CyclicBarrier cyclicBarrier;
public Athlete(String name, CyclicBarrier cyclicBarrier) { super(); this.name = name; this.cyclicBarrier = cyclicBarrier; }
@Override public void run() { int readyTime = new Random().nextInt(5) * 1000; System.out.println("運動員準備時間:" + readyTime);
try { Thread.sleep(readyTime); cyclicBarrier.await(); } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); }
System.out.println("開跑。。。"); } } |
Semaphore
信號量,是用於線程線程同時運行的數量,非常適合高併發訪問,拿到信號量的線程可以進入,否則就等待,通過acquire()和release()獲取和釋放訪問許可。
public class U03Semaphore { public static void main(String[] args) {
//線程池 ExecutorService pool = Executors.newCachedThreadPool();
//每次只允許3個線程同時處理任務 Semaphore semaphore = new Semaphore(3);
//模擬 for (int i = 0; i < 100; i++) { int num = i; pool.execute(new Runnable() { @Override public void run() {
try { //獲得許可 semaphore.acquire();
System.out.println(num + " 處理......"); Thread.sleep(new Random().nextInt(3) * 1000);
//處理完業務邏輯釋放 semaphore.release(); } catch (InterruptedException e) { e.printStackTrace(); } } }); }
pool.shutdown(); } } |