当前位置:

synchronized、ReentrantLock、Semaphore、CountDownLatch 的案例代码

机器助手 |  2025-07-13
 68人浏览

以下是使用 Java 中的 synchronized、ReentrantLock、Semaphore、CountDownLatch 的案例代码:
使用 synchronized 实现线程互斥
public class SynchronizedExample {  
   private static int count = 0;
   public static void main(String[] args) {  
       Thread t1 = new Thread(new Runnable() {  
           public void run() {  
               synchronized (SynchronizedExample.class) {  
                   for (int i = 0; i < 1000; i++) {  
                       count++;  
                   }  
               }  
           }  
       });
       Thread t2 = new Thread(new Runnable() {  
           public void run() {  
               synchronized (SynchronizedExample.class) {  
                   for (int i = 0; i < 1000; i++) {  
                       count++;  
                   }  
               }  
           }  
       });
       t1.start();  
       t2.start();  
   }  
}
上述代码中,我们使用 synchronized 关键字修饰 count 变量所在的类,实现了线程互斥。t1 和 t2 两个线程同时访问 count 变量时,只有一个线程能够成功,另一个线程会被阻塞。
使用 ReentrantLock 实现线程互斥
public class ReentrantLockExample {  
   private static int count = 0;  
   private ReentrantLock lock = new ReentrantLock();
   public static void main(String[] args) {  
       Thread t1 = new Thread(new Runnable() {  
           public void run() {  
               lock.lock();  
               try {  
                   for (int i = 0; i < 1000; i++) {  
                       count++;  
                   }  
               } finally {  
                   lock.unlock();  
               }  
           }  
       });
       Thread t2 = new Thread(new Runnable() {  
           public void run() {  
               lock.lock();  
               try {  
                   for (int i = 0; i < 1000; i++) {  
                       count++;  
                   }  
               } finally {  
                   lock.unlock();  
               }  
           }  
       });
       t1.start();  
       t2.start();  
   }  
}
上述代码中,我们使用 ReentrantLock 实现了线程互斥。t1 和 t2 两个线程同时访问 count 变量时,只有一个线程能够成功,另一个线程会被阻塞。与 synchronized 关键字不同,ReentrantLock 允许多个线程同时获取锁,但同一个线程不能多次获取锁。
使用 Semaphore 实现线程互斥
public class SemaphoreExample {  
   private Semaphore semaphore = new Semaphore(1, 1);
   public static void main(String[] args) {  
       Thread t1 = new Thread(new Runnable() {  
           public void run() {  
               semaphore.acquire();  
               try {  
                   for (int i = 0; i < 1000; i++) {  
                       // Do something  
                   }  
               } finally {  
                   semaphore.release();  
               }  
           }  
       });
       Thread t2 = new Thread(new Runnable() {  
           public void run() {  
               semaphore.acquire();  
               try {  
                   for (int i = 0; i < 1000; i++) {  
                       // Do something  
                   }  
               } finally {  
                   semaphore.release();  
               }  
           }  
       });
       t1.start();  
       t2.start();  
   }  
}
上述代码中,我们使用 Semaphore 实现了线程互斥。t1 和 t2 两个线程同时访问 semaphore 信号量时,只有一个线程能够成功,另一个线程会被阻塞。Semaphore 信号量允许多个线程同时获取,但获取到的线程数不超过信号量的计数器值。

CountDownLatch 是 Java 并发编程中的一个同步工具,它可以用于实现线程间的同步。CountDownLatch 通过一个计数器来控制线程的同步,当计数器的值为 0 时,线程会被阻塞直到其他线程释放锁。
下面是一个使用 CountDownLatch 实现线程同步的示例代码:
import java.util.concurrent.CountDownLatch;  
import java.util.concurrent.locks.ReentrantLock;
public class CountDownLatchExample {  
   private static final Object LOCK = new Object();  
   private static CountDownLatch countDownLatch;
   public static void main(String[] args) {  
       ReentrantLock lock = new ReentrantLock();  
       countDownLatch = new CountDownLatch(1);
       Thread t1 = new Thread(new Runnable() {  
           @Override  
           public void run() {  
               lock.lock();  
               try {  
                   System.out.println("Thread 1 started");  
                   countDownLatch.countDown();  
                   System.out.println("Thread 1 finished");  
               } finally {  
                   lock.unlock();  
               }  
           }  
       });
       Thread t2 = new Thread(new Runnable() {  
           @Override  
           public void run() {  
               lock.lock();  
               try {  
                   while (countDownLatch.getCount() > 0) {  
                       System.out.println("Thread 2 waiting");  
                       countDownLatch.wait();  
                   }  
                   System.out.println("Thread 2 started");  
                   countDownLatch.countDown();  
                   System.out.println("Thread 2 finished");  
               } finally {  
                   lock.unlock();  
               }  
           }  
       });
       t1.start();  
       t2.start();  
   }  
}
在这个示例中,我们使用了一个 ReentrantLock 和一个 CountDownLatch 来实现线程同步。ReentrantLock 用于保护共享资源,而 CountDownLatch 用于控制线程的同步。
当 t1 线程开始执行时,它会先获取锁,然后调用 countDownLatch.countDown() 方法将计数器的值减 1。接着,t2 线程会等待计数器的值变为 0,然后开始执行。在 t2 线程执行过程中,它会先将计数器的值减 1,然后唤醒 t1 线程。
通过使用 CountDownLatch,我们可以实现线程间的同步,确保共享资源被正确地访问和修改。

文章评论