Java互斥实例

时间:2020-02-23 14:37:12  来源:igfitidea点击:

在深入了解互斥体是什么之前,让我们先举个例子:

想想排队吧。不管长短。现在想想一辆卖游乐园门票的卡车。一次一个人可以买票。当这个人买了票,就到了排队的下一个人的时间了。

Mutex允许每个线程有一个许可证,换句话说,一次只能有一个线程访问这些资源。在上面的类比中,两个人不能同时买票。互斥也是一样。只是代替了人,它是线程,而不是票,它是一个许可证。差不多是一样的。。

互斥体与信号量稍有不同, 信号量允许多个线程访问资源。也就是说,多个人可以同时买票。

构造函数

  • public Semaphore(int permits);
  • public Semaphore(int permits, boolean fair);

第一个构造函数是我们实际上可以区分互斥体和信号量的地方。如果我们有1作为参数,那意味着只有1个线程被允许获取锁。请记住,由于它不接受第二个参数 boolean fair,所以我们要让信号量类以任何顺序提供对任何线程的访问。

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

互斥基本代码实现

import java.util.concurrent.Semaphore;

public class MutexDemo {

  //create a Semaphore instance that makes it so only 1 thread can access resource at a time
  private static Semaphore mutex = new Semaphore(1);

  static class ThreadDemo extends Thread {

		private String name = "";

		public ThreadDemo(String name) {
		    this.name = name;
		}

		@Override
		public void run() {
		    try {
                              // check the above mentioned analogy in the article for reference
				System.out.println("How many people can buy a ticket at a time: " + mutex.availablePermits());
				System.out.println(name + " is buying a ticket..."); 
				mutex.acquire();
				try {
					Thread.sleep(1000);

					System.out.println(name + " is still buying a ticket. How many people can still buy the ticket alongside him: " + mutex.availablePermits());
				} finally {
					mutex.release();
					System.out.println(name + " bought the ticket.");
					System.out.println("How many people can buy tickets after " + name + " has finished buying the ticket: " + mutex.availablePermits());
				}
		    } catch (Exception e) {
		    	e.printStackTrace();
		    }
		}
  }

  public static void main(String[] args) {

	ThreadDemo thread1 = new ThreadDemo("Bob");
	thread1.start();

	ThreadDemo thread2 = new ThreadDemo("Charlie");
	thread2.start();

	ThreadDemo thread3 = new ThreadDemo("Christie");
	thread3.start();

  }
}

输出

How many people can buy a ticket at a time: 1
Bob is buying a ticket...
How many people can buy a ticket at a time: 0
Charlie is buying a ticket...
How many people can buy a ticket at a time: 0
Christie is buying a ticket...
Bob is still buying a ticket. How many people can still buy the ticket alongside him: 0
Bob bought the ticket.
How many people can buy tickets after Bob has finished buying the ticket: 1
Charlie is still buying a ticket. How many people can still buy the ticket alongside him: 0
Charlie bought the ticket.
How many people can buy tickets after Charlie has finished buying the ticket: 1
Christie is still buying a ticket. How many people can still buy the ticket alongside him: 0
Christie bought the ticket.
How many people can buy tickets after Christie has finished buying the ticket: 1

从输出可以看出, 有人买票,其他人买不到。这是其中一行:

*鲍勃还在买票。还有多少人能在他身边买到票: 0*

然而,他“买”了票后,紧接着,对方就买票了。

归根结底,是acquire()和release()。acquire()是指某人开始“购买票证”,release()是指“购买票证”的人。