首页常见问题正文

Java中都有哪些同步器?

更新时间:2023-04-06 来源:黑马程序员 浏览量:

IT培训班

  Java中常用的同步器包括:

  1.synchronized关键字

  在Java中,使用synchronized关键字可以对代码块或方法进行同步,使得在同一时刻只有一个线程可以执行该代码块或方法。

  下面是一个使用synchronized关键字同步的示例代码:

public class SynchronizedExample {
    private int count = 0;

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

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

  2.ReentrantLock类

  ReentrantLock是一个可重入的互斥锁,它可以和synchronized关键字一样实现对临界区的同步。使用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是一个信号量,它可以限制同时访问某一资源的线程数量。Semaphore可以用来实现生产者-消费者模型等。

  下面是一个使用Semaphore实现生产者-消费者模型的示例代码:

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一起使用,可以实现更加灵活的线程同步。

  下面是一个使用Condition实现等待-通知模型的示例代码:

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是一个同步工具类,它可以使一个或多个线程等待其他线程完成操作后再执行。CountDownLatch的使用需要指定计数器的初始值,并通过await()方法等待计数器归零,同时通过countDown()方法将计数器减一。

  下面是一个使用CountDownLatch实现等待其他线程完成操作的示例代码:

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() + "执行完成");
                // 计数器减一
                latch.countDown();
            });
            thread.start();
        }
        // 等待计数器归零
        latch.await();
        System.out.println("所有线程执行完成");
    }
}

  6.CyclicBarrier类

  CyclicBarrier也是一个同步工具类,它可以使一组线程相互等待,直到所有线程都到达某个屏障点后再同时执行。CyclicBarrier的使用需要指定参与线程的数量,并通过await()方法等待所有线程到达屏障点,同时通过reset()方法将屏障重置,可以用于多次使用。

  下面是一个使用CyclicBarrier实现线程同步的示例代码:

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("所有线程执行完成");
        });
        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() + "执行完成");
                try {
                    // 等待其他线程
                    barrier.await();
                } catch (InterruptedException | BrokenBarrierException e) {
                    e.printStackTrace();
                }
            });
            thread.start();
        }
    }
}

  以上是Java中常用的同步器,不同的同步器有着不同的适用场景和使用方式,需要根据实际情况选择合适的同步器进行使用。

分享到:
在线咨询 我要报名
和我们在线交谈!