更新時(shí)間:2023-04-06 來源:黑馬程序員 瀏覽量:
Java中常用的同步器包括:
在Java中,使用synchronized關(guān)鍵字可以對代碼塊或方法進(jìn)行同步,使得在同一時(shí)刻只有一個線程可以執(zhí)行該代碼塊或方法。
下面是一個使用synchronized關(guān)鍵字同步的示例代碼:
public class SynchronizedExample { private int count = 0; public synchronized void increment() { count++; } public synchronized int getCount() { return count; } }
ReentrantLock是一個可重入的互斥鎖,它可以和synchronized關(guān)鍵字一樣實(shí)現(xiàn)對臨界區(qū)的同步。使用ReentrantLock時(shí)需要手動獲取和釋放鎖。
下面是一個使用ReentrantLock同步的示例代碼:
import java.util.concurrent.locks.ReentrantLock; public class ReentrantLockExample { private int count = 0; private ReentrantLock lock = new ReentrantLock(); public void increment() { lock.lock(); try { count++; } finally { lock.unlock(); } } public int getCount() { lock.lock(); try { return count; } finally { lock.unlock(); } } }
Semaphore是一個信號量,它可以限制同時(shí)訪問某一資源的線程數(shù)量。Semaphore可以用來實(shí)現(xiàn)生產(chǎn)者-消費(fèi)者模型等。
下面是一個使用Semaphore實(shí)現(xiàn)生產(chǎn)者-消費(fèi)者模型的示例代碼:
import java.util.concurrent.Semaphore; public class SemaphoreExample { private final Semaphore producerSemaphore = new Semaphore(1); private final Semaphore consumerSemaphore = new Semaphore(0); private int data; public void produce(int newData) throws InterruptedException { producerSemaphore.acquire(); data = newData; consumerSemaphore.release(); } public int consume() throws InterruptedException { consumerSemaphore.acquire(); int consumedData = data; producerSemaphore.release(); return consumedData; } }
Condition是一個條件變量,它可以和Lock一起使用,可以實(shí)現(xiàn)更加靈活的線程同步。
下面是一個使用Condition實(shí)現(xiàn)等待-通知模型的示例代碼:
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class ConditionExample { private int data; private Lock lock = new ReentrantLock(); private Condition notEmpty = lock.newCondition(); private Condition notFull = lock.newCondition(); private boolean full = false; public void put(int newData) throws InterruptedException { lock.lock(); try { while (full) { notFull.await(); } data = newData; full = true; notEmpty.signal(); } finally { lock.unlock(); } } public int take() throws InterruptedException { lock.lock(); try { while (!full) { notEmpty.await(); } int takenData = data; full = false; notFull.signal(); return takenData; } finally { lock.unlock(); } } }
CountDownLatch是一個同步工具類,它可以使一個或多個線程等待其他線程完成操作后再執(zhí)行。CountDownLatch的使用需要指定計(jì)數(shù)器的初始值,并通過await()方法等待計(jì)數(shù)器歸零,同時(shí)通過countDown()方法將計(jì)數(shù)器減一。
下面是一個使用CountDownLatch實(shí)現(xiàn)等待其他線程完成操作的示例代碼:
import java.util.concurrent.CountDownLatch; public class CountDownLatchExample { public static void main(String[] args) throws InterruptedException { int count = 5; CountDownLatch latch = new CountDownLatch(count); for (int i = 0; i < count; i++) { Thread thread = new Thread(() -> { // 模擬線程操作 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("線程" + Thread.currentThread().getName() + "執(zhí)行完成"); // 計(jì)數(shù)器減一 latch.countDown(); }); thread.start(); } // 等待計(jì)數(shù)器歸零 latch.await(); System.out.println("所有線程執(zhí)行完成"); } }
CyclicBarrier也是一個同步工具類,它可以使一組線程相互等待,直到所有線程都到達(dá)某個屏障點(diǎn)后再同時(shí)執(zhí)行。CyclicBarrier的使用需要指定參與線程的數(shù)量,并通過await()方法等待所有線程到達(dá)屏障點(diǎn),同時(shí)通過reset()方法將屏障重置,可以用于多次使用。
下面是一個使用CyclicBarrier實(shí)現(xiàn)線程同步的示例代碼:
import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; public class CyclicBarrierExample { public static void main(String[] args) { int count = 3; CyclicBarrier barrier = new CyclicBarrier(count, () -> { System.out.println("所有線程執(zhí)行完成"); }); for (int i = 0; i < count; i++) { Thread thread = new Thread(() -> { // 模擬線程操作 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("線程" + Thread.currentThread().getName() + "執(zhí)行完成"); try { // 等待其他線程 barrier.await(); } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); } }); thread.start(); } } }
以上是Java中常用的同步器,不同的同步器有著不同的適用場景和使用方式,需要根據(jù)實(shí)際情況選擇合適的同步器進(jìn)行使用。