原文: https://javatutorial.net/java-mutex-example

在更深入地了解互斥量之前,先给出一个示例:

想想一个队列。 不管长短,都没关系。 现在想想一辆正在出售游乐园门票的卡车。 一次一个人可以买票。 该人买了票后,就该排队了。

这个小故事与理解互斥量有什么关系? 让我解释。

Java 互斥量示例 - 图1

互斥量允许每个线程具有 1 个许可。换句话说,一次只能有 1 个线程可以访问资源。 在上面的类比中,两个人不能同时购买门票。互斥量也是如此。 它不是线程,而是人员,而是票证。 同样的事情或多或少..

互斥量与Semaphore略有不同,因此Semaphore允许多个线程访问资源。意思是,多个人可以同时购买门票。

Java 互斥量示例 - 图2

构造器

  1. public Semaphore(int permits)
  2. public Semaphore(int permits, boolean fair)

第一个构造函数是我们实际上可以区分互斥量和Semaphore的地方。 如果那里有 1 作为参数,则意味着将只允许 1 个线程获取锁。 请记住,由于它没有第二个参数boolean fair,因此您正在使Semaphore类以任何顺序访问任何线程。

第二个构造函数如果传递true(公平),则确保按线程请求访问并在队列中等待的顺序给出访问。

互斥量基本代码实现

  1. import java.util.concurrent.Semaphore;
  2. public class MutexDemo {
  3. // create a Semaphore instance that makes it so only 1 thread can access resource at a time
  4. private static Semaphore mutex = new Semaphore(1);
  5. static class ThreadDemo extends Thread {
  6. private String name = "";
  7. public ThreadDemo(String name) {
  8. this.name = name;
  9. }
  10. @Override
  11. public void run() {
  12. try {
  13. // check the above mentioned analogy in the article for reference
  14. System.out.println("How many people can buy a ticket at a time: " + mutex.availablePermits());
  15. System.out.println(name + " is buying a ticket...");
  16. mutex.acquire();
  17. try {
  18. Thread.sleep(1000);
  19. System.out.println(name + " is still buying a ticket. How many people can still buy the ticket alongside him: " + mutex.availablePermits());
  20. } finally {
  21. mutex.release();
  22. System.out.println(name + " bought the ticket.");
  23. System.out.println("How many people can buy tickets after " + name + " has finished buying the ticket: " + mutex.availablePermits());
  24. }
  25. } catch (Exception e) {
  26. e.printStackTrace();
  27. }
  28. }
  29. }
  30. public static void main(String[] args) {
  31. ThreadDemo thread1 = new ThreadDemo("Bob");
  32. thread1.start();
  33. ThreadDemo thread2 = new ThreadDemo("Charlie");
  34. thread2.start();
  35. ThreadDemo thread3 = new ThreadDemo("Christie");
  36. thread3.start();
  37. }
  38. }

输出

  1. How many people can buy a ticket at a time: 1
  2. Bob is buying a ticket...
  3. How many people can buy a ticket at a time: 0
  4. Charlie is buying a ticket...
  5. How many people can buy a ticket at a time: 0
  6. Christie is buying a ticket...
  7. Bob is still buying a ticket. How many people can still buy the ticket alongside him: 0
  8. Bob bought the ticket.
  9. How many people can buy tickets after Bob has finished buying the ticket: 1
  10. Charlie is still buying a ticket. How many people can still buy the ticket alongside him: 0
  11. Charlie bought the ticket.
  12. How many people can buy tickets after Charlie has finished buying the ticket: 1
  13. Christie is still buying a ticket. How many people can still buy the ticket alongside him: 0
  14. Christie bought the ticket.
  15. How many people can buy tickets after Christie has finished buying the ticket: 1

从输出中可以看到,当有人买票时,没有其他人可以买。这是显示以下内容的行之一:

Bob 仍在买票。 还有多少人可以和他一起买票: 0

但是,在他“购买”了机票之后,其他人立即购买了机票。

归根结底,它涉及acquire()release()acquire()是指该人开始“购买机票”的时间,release()是指该人“购买机票”的时间。