Semaphore的使用

简介:

  Semaphore也是一个线程同步的辅助类,可以维护当前访问自身的线程个数,并提供了同步机制。使用Semaphore可以控制同时访问资源的线程个数,例如,实现一个文件允许的并发访问数。

Semaphore的主要方法摘要:

  void acquire()**:**从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断。

  void release():释放一个许可,将其返回给信号量。

  int availablePermits():返回此信号量中当前可用的许可数。

  boolean hasQueuedThreads():查询是否有线程正在等待获取。

下面是一个例子:


 1 package com.thread;
 2
 3 import java.util.concurrent.ExecutorService;
 4 import java.util.concurrent.Executors;
 5 import java.util.concurrent.Semaphore;
 6
 7 public class SemaphoreTest {
 8     public static void main(String[] args) {
 9         ExecutorService service = Executors.newCachedThreadPool();
10         final  Semaphore sp = new Semaphore(3);//创建Semaphore信号量,初始化许可大小为3
11         for(int i=0;i<10;i++){
12             try {
13                 Thread.sleep(100);
14             } catch (InterruptedException e2) {
15                 e2.printStackTrace();
16             }
17             Runnable runnable = new Runnable(){
18                     public void run(){
19                     try {
20                         sp.acquire();//请求获得许可,如果有可获得的许可则继续往下执行,许可数减1。否则进入阻塞状态
21                     } catch (InterruptedException e1) {
22                         e1.printStackTrace();
23                     }
24                     System.out.println(“线程” + Thread.currentThread().getName() +
25                             “进入,当前已有” + (3-sp.availablePermits()) + “个并发”);
26                     try {
27                         Thread.sleep((long)(Math.random()*10000));
28                     } catch (InterruptedException e) {
29                         e.printStackTrace();
30                     }
31                     System.out.println(“线程” + Thread.currentThread().getName() +
32                             “即将离开”);
33                     sp.release();//释放许可,许可数加1
34                     //下面代码有时候执行不准确,因为其没有和上面的代码合成原子单元
35                     System.out.println(“线程” + Thread.currentThread().getName() +
36                             “已离开,当前已有” + (3-sp.availablePermits()) + “个并发”);
37                 }
38             };
39             service.execute(runnable);
40         }
41     }
42
43 }

  单个信号量的Semaphore对象可以实现互斥锁的功能,并且可以是由一个线程获得了“锁”,再由另一个线程释放“锁”,这可应用于死锁恢复的一些场合。
 1 package com.thread;
 2 import java.util.concurrent.ExecutorService;
 3 import java.util.concurrent.Executors;
 4 import java.util.concurrent.Semaphore;
 5 import java.util.concurrent.locks.Lock;
 6 import java.util.concurrent.locks.ReentrantLock;
 7
 8 public class LockTest {
 9     public static void main(String[] args) {
10         final Business business = new Business();
11         ExecutorService executor =  Executors.newFixedThreadPool(3);
12         for(int i=0;i<3;i++)
13         {
14             executor.execute(
15                     new Runnable()
16                     {
17                         public void run()
18                         {
19                             business.service();
20                         }
21                     }
22
23             );
24         }
25         executor.shutdown();
26     }
27
28     private static class Business
29     {
30         private int count;
31         Lock lock = new ReentrantLock();
32         Semaphore sp = new Semaphore(1);
33         public void service()
34         {
35             //lock.lock();
36             try {
37                 sp.acquire(); //当前线程使用count变量的时候将其锁住,不允许其他线程访问
38             } catch (InterruptedException e1) {
39                 e1.printStackTrace();
40             }
41             try {
42                 count++;
43                 try {
44                     Thread.sleep(1000);
45                 } catch (InterruptedException e) {
46                     e.printStackTrace();
47                 }
48                 System.out.println(count);
49             } catch (RuntimeException e) {
50                 e.printStackTrace();
51             }
52             finally
53             {
54                 //lock.unlock();
55                 sp.release();  //释放锁
56             }
57         }
58     }
59
60 }

相关文章
|
2月前
|
Java
JAVA并发编程系列(7)Semaphore信号量剖析
腾讯T2面试,要求在3分钟内用不超过20行代码模拟地铁安检进站过程。题目设定10个安检口,100人排队,每人安检需5秒。实际中,这种题目主要考察并发编程能力,特别是多个线程如何共享有限资源。今天我们使用信号量(Semaphore)实现,限制同时进站的人数,并通过信号量控制排队和进站流程。并详细剖析信号量核心原理和源码。
Semaphore 使用详解
本文主要对Semaphore 的相关知识点进行了介绍和讲解
105 0
|
6月前
|
数据库连接
认识 Semaphore
认识 Semaphore
48 0
|
Java 数据库连接 API
【JUC】信号量Semaphore详解
【JUC】信号量Semaphore详解
171 0
【JUC】信号量Semaphore详解
Semaphore(信号量)介绍以及实例
Semaphore(信号量)介绍以及实例
177 0
Semaphore(信号量)介绍以及实例
|
Java
呵,Semaphore ,就这?(二)
那么本篇文章我们继续来和你聊聊并发工具类的第二篇文章 --- Semaphore 。
124 0
呵,Semaphore ,就这?(二)
|
监控 数据库连接
呵,Semaphore ,就这?(一)
那么本篇文章我们继续来和你聊聊并发工具类的第二篇文章 --- Semaphore 。
125 0
呵,Semaphore ,就这?(一)
并发编程之Semaphore信号量
`Semaphore` 翻译过来就是信号量, 其根本原理就是基于 `CAS` 共享锁的一种实现。举一个例子。 假设停车场只有三个车位,一开始三个车位都是空的。这时如果同时来了五辆车,看门人允许其中三辆不受阻碍的进入,然后放下车拦,剩下的车则必须在入口等待,此后来的车也都不得不在入口处等待。这时,有一辆车离开停车场,看门人得知后,打开车拦,放入一辆,如果又离开两辆,则又可以放入两辆,如此往复。
164 0
|
Java
Java并发编程之Semaphore信号量
Java并发编程之Semaphore信号量
151 0
Java并发编程之Semaphore信号量
Semaphore信号量
Semaphore 可以用来限制或管理数量有限资源的使用情况 - 信号量的作用是用来维护一个“许可证”,的计数,线程可以获取 许可证,那信号量剩余许可证就减一,线程也可以是否一个许可证,那剩余的许可证就加一,当信号量拥有的许可证为0时,那么下一个线程想获得许可证,就要进行等待,直到另外线程释放许可证
276 0
Semaphore信号量