目錄
1. Lock機制:明鎖控制
2. 柵欄機制(CyclicBarrier)
3. 閉鎖機制(CountDownLatch)
4. 信號量機制(Semaphore)
5. 無鎖機制
1. Lock機制:明鎖控制
????????Lock接口提供了比synchronized更靈活的鎖機制,屬于明鎖(需要手動獲取和釋放鎖)。與synchronized隱式鎖不同,Lock需要顯式地調用lock()和unlock()方法。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class LockDemo {private Lock lock = new ReentrantLock();private int count = 0;public void increment() {lock.lock(); // 手動獲取鎖try {count++;} finally {lock.unlock(); // 必須在finally中手動釋放鎖}}
}
2. 柵欄機制(CyclicBarrier)
????????柵欄機制允許一組線程相互等待,直到所有線程都到達某個屏障點,然后所有線程才會繼續執行。CyclicBarrier可以重復使用,適用于分階段的任務處理。
package com.demo5;import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;/*** * 研學,旅游公司包車,一個車做4個同學,坐滿就發車; 總共有28個人,怎么控制和實現?**/public class Test {public static void main(String[] args) {// 設置屏障點CyclicBarrier cb = new CyclicBarrier(4, () -> {System.out.println("已經有4個同學了,就發車吧, 旅游車已經啟動出發");});for (int i = 0; i < 28; i++) {Runnable r = () -> {System.out.println("學生來報道............");try {cb.await();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (BrokenBarrierException e) {// TODO Auto-generated catch blocke.printStackTrace();}};try {Thread.sleep(3000);} catch (InterruptedException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}new Thread(r).start();}}}
運行結果:
3. 閉鎖機制(CountDownLatch)
????????閉鎖是一種一次性使用的同步輔助工具,允許一個或多個線程等待其他線程完成操作。
package com.demo8;import java.util.concurrent.CountDownLatch;public class Test {public static void main(String[] args) {//閉鎖,任務只能執行一次CountDownLatch cdl = new CountDownLatch(10);//10個人到了,一桌人開始吃飯,吃完就結束。for(int i=0;i<10;i++){Runnable r = ()->{System.out.println(Thread.currentThread().getName()+",來吃飯.....");cdl.countDown();//-1,一直到0};try {Thread.sleep(2000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}new Thread(r).start();}try {cdl.await(); // 等待計數器歸零,屏障點解除} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("我們開始歡樂的用餐");}}
運行結果:
4. 信號量機制(Semaphore)
????????信號量用于控制同時訪問特定資源的線程數量,通過許可證機制實現資源池的訪問控制。
package com.demo9;import java.util.Random;
import java.util.concurrent.Semaphore;public class Test {public static void main(String[] args) {Semaphore s = new Semaphore(3); // 允許3個線程同時訪問for(int i=0;i<6;i++){Runnable r = ()->{try {s.acquire(); // 獲取許可System.out.println(Thread.currentThread().getName()+", 搶優惠劵");Thread.sleep(new Random().nextInt(20)*1000);System.out.println(Thread.currentThread().getName()+", 離開現場");} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{s.release(); // 釋放許可}};new Thread(r).start();}}}
運行結果:
5. 無鎖機制
????????無鎖編程通過CAS(Compare And Swap)操作實現線程安全,避免了鎖的開銷。Java中的Atomic類就是無鎖機制的典型實現。
package com.demo3;import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;public class Test {// 原子鎖,就是無鎖private static AtomicInteger count = new AtomicInteger(0);public static void inc() {try {Thread.sleep(1);// 毫秒count.getAndIncrement();//count加1// TimeUnit.MILLISECONDS.sleep(1);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public static void main(String[] args) {CountDownLatch cd = new CountDownLatch(100);for (int i = 0; i < 100; i++) {Runnable r = () -> {Test.inc();cd.countDown();};new Thread(r).start();}try {cd.await();System.out.println("總和為:" + Test.count);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
運行結果: