在 Java 中,可以使用多种并发控制方法来管理多线程程序的执行。以下是一些常用的并发控制方法:
- synchronized 关键字:synchronized 关键字是 Java 中最基本的同步机制。它可以确保在同一时刻只有一个线程可以访问共享资源。可以通过在方法或代码块上使用 synchronized 关键字来实现同步。
public synchronized void synchronizedMethod() { // 同步代码 } public void methodWithSynchronizedBlock() { synchronized (this) { // 同步代码 } }
- ReentrantLock 类:ReentrantLock 是一个可重入的互斥锁,提供了比 synchronized 更灵活的锁定机制。可以通过实现 Runnable 或 Callable 接口并使用 ReentrantLock 来控制并发。
import java.util.concurrent.locks.ReentrantLock; public class MyRunnable implements Runnable { private final ReentrantLock lock = new ReentrantLock(); @Override public void run() { lock.lock(); try { // 同步代码 } finally { lock.unlock(); } } }
- Semaphore 类:Semaphore 是一个计数信号量,用于控制同时访问共享资源的线程数量。可以通过调用 acquire() 和 release() 方法来获取和释放许可。
import java.util.concurrent.Semaphore; public class MyRunnable implements Runnable { private final Semaphore semaphore = new Semaphore(3); // 允许最多 3 个线程同时访问 @Override public void run() { try { semaphore.acquire(); // 同步代码 } catch (InterruptedException e) { e.printStackTrace(); } finally { semaphore.release(); } } }
- CountDownLatch 类:CountDownLatch 是一个同步辅助类,允许一个或多个线程等待直到一组操作完成。可以通过调用 await() 方法来阻塞线程,直到计数器归零。
import java.util.concurrent.CountDownLatch; public class MyRunnable implements Runnable { private final CountDownLatch latch = new CountDownLatch(3); // 等待 3 个线程完成 @Override public void run() { try { // 执行任务 latch.countDown(); // 减少计数器 } catch (InterruptedException e) { e.printStackTrace(); } finally { try { latch.await(); // 等待计数器归零 } catch (InterruptedException e) { e.printStackTrace(); } } } }
- CyclicBarrier 类:CyclicBarrier 是一个同步辅助类,允许一组线程相互等待,直到所有线程都准备好继续执行。可以通过调用 await() 方法来阻塞线程,直到所有线程都达到屏障点。
import java.util.concurrent.CyclicBarrier; public class MyRunnable implements Runnable { private final CyclicBarrier barrier = new CyclicBarrier(3); // 等待 3 个线程达到屏障点 @Override public void run() { try { // 执行任务 barrier.await(); // 等待所有线程达到屏障点 } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); } } }
- Executors 和线程池:Java 提供了 Executors 框架,可以方便地创建和管理线程池。通过使用线程池,可以更有效地控制线程的创建、执行和销毁,从而提高程序的性能和可维护性。
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class MyRunnable implements Runnable { private static final ExecutorService executorService = Executors.newFixedThreadPool(3); // 创建一个包含 3 个线程的线程池 @Override public void run() { executorService.submit(this); // 将任务提交给线程池执行 } }
这些并发控制方法可以根据具体需求进行组合使用,以实现更复杂的线程同步和协作。