Java多线程同步问题:简单锁与条件变量示例

原创 - 日理万妓 2024-09-28 00:06 167阅读 0赞

在Java中,多线程的同步主要通过两种机制实现:简单锁和条件变量。

  1. 简单锁:Java中的Object类提供了synchronized关键字来声明一个代码块,这个代码块在这个对象的所有实例上都会具有相同的锁。常见的锁对象有Thread.currentThread()。

示例:

  1. public class SimpleLockExample {
  2. private Object lock = new Object();
  3. public synchronized void criticalSection() {
  4. System.out.println("Critical Section: Locking...\n");
  5. // Critical code here
  6. System.out.println("\nCritical Section: Unlocking...\n");
  7. }
  8. public static void main(String[] args) {
  9. SimpleLockExample example = new SimpleLockExample();
  10. Thread thread1 = new Thread(() -> {
  11. try {
  12. example.criticalSection();
  13. } catch (InterruptedException e) {
  14. e.printStackTrace();
  15. }
  16. }));
  17. Thread thread2 = new Thread(() -> {
  18. try {
  19. example.criticalSection();
  20. } catch (InterruptedException e) {
  21. e.printStackTrace();
  22. }
  23. }));
  24. // 启动线程
  25. thread1.start();
  26. thread2.start();
  27. // 等待所有线程执行完毕
  28. while (!thread1.isAlive() && !thread2.isAlive()) {
  29. try {
  30. Thread.sleep(100);
  31. } catch (InterruptedException e) {
  32. e.printStackTrace();
  33. }
  34. }
  35. System.out.println("\nProgram finished successfully!\n");
  36. }
  37. }

在这个示例中,我们创建了一个简单锁,它由一个对象实例化。criticalSection()方法被声明为synchronized,这意味着在同一时间只有一个线程能够访问这个代码块。

条件变量(Condition Variable)用于在满足特定条件后通知其他线程。在这个例子中,并没有直接使用条件变量,但如果需要等待某个条件出现后再执行代码,可以引入Condition对象来实现。

  1. 条件变量:Java中的 Condition接口提供了wait()和notifyAll()方法,用于实现多线程间的同步。

示例:

  1. import java.util.concurrent.Condition;
  2. import java.util.concurrent.locks.Lock;
  3. import java.util.concurrent.locks.ReentrantLock;
  4. public class ConditionVariableExample {
  5. private Lock lock = new ReentrantLock();
  6. private Condition condition = lock.newCondition();
  7. public void criticalSection() {
  8. try {
  9. lock.lock(); // 获取锁
  10. System.out.println("Critical Section: Locking...\n");
  11. // Critical code here
  12. System.out.println("\nCritical Section: Unlocking...\n");
  13. } catch (InterruptedException e) {
  14. e.printStackTrace();
  15. } finally {
  16. try {
  17. lock.unlock(); // 释放锁
  18. } catch (InterruptedException e) {
  19. e.printStackTrace();
  20. }
  21. }
  22. condition.signalAll(); // 唤醒所有等待的线程
  23. }
  24. public static void main(String[] args) {
  25. ConditionVariableExample example = new ConditionVariableExample();
  26. Thread thread1 = new Thread(() -> {
  27. try {
  28. example.criticalSection();
  29. } catch (InterruptedException e) {
  30. e.printStackTrace();
  31. }
  32. System.out.println("\nThread 1 finished execution...\n");
  33. condition.await(); // 等待条件满足
  34. System.out.println("Condition satisfied. All threads notified.\n");
  35. }));
  36. Thread thread2 = new Thread(() -> {
  37. try {
  38. example.criticalSection();
  39. } catch (InterruptedException e) {
  40. e.printStackTrace();
  41. }
  42. System.out.println("\nThread 2 finished execution...\n");
  43. condition.signalAll(); // 唤醒所有等待的线程
  44. }));
  45. // 启动线程
  46. thread1.start();
  47. thread2.start();
  48. // 等待所有线程执行完毕
  49. while (!thread1.isAlive() && !thread2.isAlive()) {
  50. try {
  51. Thread.sleep(100);
  52. } catch (InterruptedException e) {
  53. e.printStackTrace();
  54. }
  55. }
  56. System.out.println("\nProgram finished successfully!\n");
  57. }
  58. }

在这个例子中,我们创建了一个简单的线程同步场景。criticalSection()方法被设计为一个需要锁定资源才能执行的代码块。

通过使用ReentrantLock和Condition接口,当多个线程同时尝试进入临界区时,可以保证只有当前持有锁的线程才能执行代码。

在条件满足时,调用condition.signalAll()来唤醒所有等待条件满足的线程。

文章版权声明:注明蒲公英云原创文章,转载或复制请以超链接形式并注明出处。

发表评论

表情:
评论列表 (有 0 条评论,167人围观)

还没有评论,来说两句吧...

相关阅读