Java信号量示例

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

信号量可以用来限制并发线程的数量,实际上,这个类维护一组许可证。

acquire()从信号量获取许可证,release()将许可证返回给信号量。如果没有许可证,acuire()将阻塞,直到有一个许可证可用

信号量用于控制对特定资源的访问。

工作流程

用计数值设置信号量。然后线程尝试获取permit,如果计数为0或者小于0,则线程将被阻塞并等待下一个许可(如果有)。此操作将一直进行,直到计数大于0。如果是,信号量将提供对线程资源的访问。线程将释放许可证,计数将增加1.

构造函数

Semaphore(int permits): 使用给定的许可数量和非公平性设置创建一个信号量

Semaphore(int permits, boolean fair):创建一个具有给定许可数量和给定公平性设置的信号量

主要方法

void acquire():从当前信号量获取许可,阻塞直到有一个可用,或者线程被中断。

voidacquire(intpermits):从当前信号量获取指定的许可数,阻塞直到所有许可证可用或者线程中断。

int availablePermites():返回当前信号量中可用的许可证数

要查看所有方法,请单击此处。我们将被重定向到Oracle官方文档。

信号量可用于锁定对特定资源的访问。每个线程都必须请求“权限”,因此需要在访问资源之前调用方法acquire()。当线程不再需要资源时,它必须调用release()来释放锁。

import java.util.concurrent.Semaphore;

public class SemaphoreDemo {

	public static void main(String[] args) throws Exception {	
		Semaphore semExample = new Semaphore(1);
		System.out.println("Available permits: " + semExample.availablePermits());

		semExample.release();

		System.out.println("Available permits: " + semExample.availablePermits());

		semExample.acquire();

		System.out.println("Available permits: " + semExample.availablePermits());

		semExample.acquire();

		System.out.println("Available permits: " + semExample.availablePermits());

		semExample.acquire();
		System.out.println("Available permits: " + semExample.availablePermits());
	}
}

输出

Available permits: 1
Available permits: 2
Available permits: 1
Available permits: 0

从上面的示例中可以看到,当我们调用release()时,我们正在向信号量实例添加一个许可证。调用acquire()时,将删除permit()。当没有许可证而我们调用acquire时,它将等待直到许可证被释放,因此在上面的示例中,最后一个print语句永远不会执行。

当你有1个permit,然后你有一个acquire()调用,紧接着是release()调用,它被称为

import java.util.concurrent.Semaphore;

public class SemaphoreDemo {

  Semaphore thread = new Semaphore(1);

  public static void main(String args[]) {
      final SemaphoreDemo test = new SemaphoreDemo();
      new Thread(){
          @Override
          public void run(){
            test.mutualExclusion(); 
          }
      }.start();

      new Thread(){
          @Override
          public void run(){
            test.mutualExclusion(); 
          }
      }.start();

  }

  private void mutualExclusion() {
      try {
      	System.out.println(Thread.currentThread().getName() + " is waiting to acquire a permit.");
      	thread.acquire();
          System.out.println("Permit has been acquired to " + Thread.currentThread().getName());
          Thread.sleep(1000);

      } catch (InterruptedException e) {
          e.printStackTrace();
      } finally {
      	System.out.println(Thread.currentThread().getName() + " is releasing the permit...");
          thread.release();
          System.out.println("Released.");
      }
  } 

}

输出

Thread-0 is waiting to acquire a permit.
Permit has been acquired to Thread-0
Thread-1 is waiting to acquire a permit.
Thread-0 is releasing the permit...
Released.
Permit has been acquired to Thread-1
Thread-1 is releasing the permit...
Released.

从Thread-0允许获取后的输出中可以看到,线程1开始等待为自己获取许可,但它(Thread-1)只在Thread-0释放它的许可时才获得许可。