首頁常見問題正文

Java中都有哪些同步器?

更新時間:2023-04-06 來源:黑馬程序員 瀏覽量:

IT培訓班

  Java中常用的同步器包括:

  1.synchronized關鍵字

  在Java中,使用synchronized關鍵字可以對代碼塊或方法進行同步,使得在同一時刻只有一個線程可以執(zhí)行該代碼塊或方法。

  下面是一個使用synchronized關鍵字同步的示例代碼:

public class SynchronizedExample {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }

    public synchronized int getCount() {
        return count;
    }
}

  2.ReentrantLock類

  ReentrantLock是一個可重入的互斥鎖,它可以和synchronized關鍵字一樣實現(xiàn)對臨界區(qū)的同步。使用ReentrantLock時需要手動獲取和釋放鎖。

  下面是一個使用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();
        }
    }
}

  3.Semaphore類

  Semaphore是一個信號量,它可以限制同時訪問某一資源的線程數(shù)量。Semaphore可以用來實現(xiàn)生產(chǎn)者-消費者模型等。

  下面是一個使用Semaphore實現(xiàn)生產(chǎn)者-消費者模型的示例代碼:

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;
    }
}

  4.Condition接口

  Condition是一個條件變量,它可以和Lock一起使用,可以實現(xiàn)更加靈活的線程同步。

  下面是一個使用Condition實現(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();
        }
    }
}

  5.CountDownLatch類

  CountDownLatch是一個同步工具類,它可以使一個或多個線程等待其他線程完成操作后再執(zhí)行。CountDownLatch的使用需要指定計數(shù)器的初始值,并通過await()方法等待計數(shù)器歸零,同時通過countDown()方法將計數(shù)器減一。

  下面是一個使用CountDownLatch實現(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í)行完成");
                // 計數(shù)器減一
                latch.countDown();
            });
            thread.start();
        }
        // 等待計數(shù)器歸零
        latch.await();
        System.out.println("所有線程執(zhí)行完成");
    }
}

  6.CyclicBarrier類

  CyclicBarrier也是一個同步工具類,它可以使一組線程相互等待,直到所有線程都到達某個屏障點后再同時執(zhí)行。CyclicBarrier的使用需要指定參與線程的數(shù)量,并通過await()方法等待所有線程到達屏障點,同時通過reset()方法將屏障重置,可以用于多次使用。

  下面是一個使用CyclicBarrier實現(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ù)實際情況選擇合適的同步器進行使用。

分享到:
在線咨詢 我要報名
和我們在線交談!