更新时间:2023-04-06 来源:黑马程序员 浏览量:
Java中常用的同步器包括:
在Java中,使用synchronized关键字可以对代码块或方法进行同步,使得在同一时刻只有一个线程可以执行该代码块或方法。
下面是一个使用synchronized关键字同步的示例代码:
public class SynchronizedExample { private int count = 0; public synchronized void increment() { count++; } public synchronized int getCount() { return count; } }
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(); } } }
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; } }
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(); } } }
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("所有线程执行完成"); } }
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中常用的同步器,不同的同步器有着不同的适用场景和使用方式,需要根据实际情况选择合适的同步器进行使用。