9、Semaphore

java.util.concurrent

Class Semaphore

Semaphore常用来限制一定数量的线程来访问某个共享资源。一个Semaphore控制了一组令牌。除非存在可使用的令牌否则在调用acquire去获得资源时

将会被阻塞。release方法就是释放令牌,潜在的能够为acquire提供令牌,使得令牌的重复利用。然而,并没有真实的令牌对象,Semaphore仅仅只是拥有

一个数字。

在获得资源前,每个线程必须从Semaphore获得一个令牌。

一个Semaphore被初始化为1,也就是Semaphore只有一个令牌可用,于是可以作为互斥锁来使用。这就是我们众所周知的二进制Semaphore,因为它只有两种

状态:如果为1,则有一个令牌可使用,如果为0,则没有令牌可使用。

它的构造函数可以接受一个boolean型的可选参数。如果我们设置为false,就不能保证线程以什么样的顺序获得令牌。如果设置为true,就会以先进先出的顺序获得

令牌。

 1 class Pool {
 2        private static final int MAX_AVAILABLE = 100;
 3        private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);
 4
 5        public Object getItem() throws InterruptedException {
 6          available.acquire();
 7          return getNextAvailableItem();
 8        }
 9
10        public void putItem(Object x) {
11          if (markAsUnused(x))
12            available.release();
13        }
14
15        // 没有一个特殊有效的数据结构这个仅仅只是作为例子
16
17        protected Object[] items =new Object[10000]; //任何所管理的项
18        protected boolean[] used = new boolean[MAX_AVAILABLE];
19
20        protected synchronized Object getNextAvailableItem() {
21          for (int i = 0; i < MAX_AVAILABLE; ++i) {
22            if (!used[i]) {
23               used[i] = true;
24               return items[i];
25            }
26          }
27          return null; // 不能到达
28        }
29
30        protected synchronized boolean markAsUnused(Object item) {
31          for (int i = 0; i < MAX_AVAILABLE; ++i) {
32            if (item == items[i]) {
33               if (used[i]) {
34                 used[i] = false;
35                 return true;
36               } else
37                 return false;
38            }
39          }
40          return false;
41        }
42
43  }

程序分析:

1、这里设置了有100个令牌的Semaphore。刚开始的时候,没有想明白,既然要给容器加上同步方法,还有必要加上Semaphore么?不管你放多少个线程进来,同时只能有一个线程能进行操作。

换一种想法,100个方法同步,与10000个方法同步,哪个对容器的影响大一些?就好像今天早上,我去坐北京天通苑的地铁,正常通向地铁的正门是被锁着的,而人群在两道铁门之间经过地铁站

中部然后迂回至正门。Semaphore就充当着两到铁门所围起来的空间的作用(如果空间被他人占用了,就没法前进),充当了一个缓冲作用。

2、Semaphore充当的缓冲作用,Semaphore并不提供同步,这也是为什么一定要给容器加上同步方法的原因。

时间: 2024-08-02 08:10:12

9、Semaphore的相关文章

Java多线程20:多线程下的其他组件之CountDownLatch、Semaphore、Exchanger

前言 在多线程环境下,JDK给开发者提供了许多的组件供用户使用(主要在java.util.concurrent下),使得用户不需要再去关心在具体场景下要如何写出同时兼顾线程安全性与高效率的代码.之前讲过的线程池.BlockingQueue都是在java.util.concurrent下的组件,Timer虽然不在java.util.concurrent下,但也算是.后两篇文章将以例子的形式简单讲解一些多线程下其他组件的使用,不需要多深刻的理解,知道每个组件大致什么作用就行. 本文主要讲解的是Cou

java并发之CountDownLatch、Semaphore和CyclicBarrier

JAVA并发包中有三个类用于同步一批线程的行为,分别是CountDownLatch.Semaphore和CyclicBarrier. CountDownLatch CountDownLatch是一个计数器闭锁,主要的功能就是通过await()方法来阻塞住当前线程,然后等待计数器减少到0了,再唤起这些线程继续执行. 这个类里主要有两个方法,一个是向下减计数器的方法:countdown(),其实现的核心代码如下: public boolean tryReleaseShared(int release

并发工具类:CountDownLatch、CyclicBarrier、Semaphore

在多线程的场景下,有些并发流程需要人为来控制,在JDK的并发包里提供了几个并发工具类:CountDownLatch.CyclicBarrier.Semaphore. 一.CountDownLatch 1 import java.util.concurrent.CountDownLatch; 2 3 4 public class CountDownLatchTest 5 { //设置N为2 6 static CountDownLatch c = new CountDownLatch(2); 7 p

使用Java辅助类(CountDownLatch、CyclicBarrier、Semaphore)并发编程

在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法 一.CountDownLatch用法 CountDownLatch类位于java.util.concurrent包下,利用它可以实现类似计数器的功能.比如有一个任务A,它要等待其他4个任务执行完毕之后才能执行,此时就可以利用CountDownLatch来实现这种功能了. CountDownLatch类只提

转发---[沧海拾遗]java并发之CountDownLatch、Semaphore和CyclicBarrier

JAVA并发包中有三个类用于同步一批线程的行为,分别是CountDownLatch.Semaphore和CyclicBarrier. CountDownLatch CountDownLatch是一个计数器闭锁,主要的功能就是通过await()方法来阻塞住当前线程,然后等待计数器减少到0了,再唤起这些线程继续执行. 这个类里主要有两个方法,一个是向下减计数器的方法:countdown(),其实现的核心代码如下: public boolean tryReleaseShared(int release

多线程同步与并发访问共享资源工具—Lock、Monitor、Mutex、Semaphore

"线程同步"的含义 当一个进程启动了多个线程时,如果需要控制这些线程的推进顺序(比如A线程必须等待B和C线程执行完毕之后才能继续执行),则称这些线程需要进行"线程同步(thread synchronization)". 线程同步的道理虽然简单,但却是给多线程开发带来复杂性的根源之一.当线程同步不好时,有可能会出现一种特殊的情形--死锁(Dead Lock). "死锁"的含义 死锁表示系统进入了一个僵化状态,所有线程都没有执行完毕,但却谁也没法继续

并发编程(七)——AbstractQueuedSynchronizer 之 CountDownLatch、CyclicBarrier、Semaphore 源码分析

这篇,我们的关注点是 AQS 最后的部分,共享模式的使用.本文先用 CountDownLatch 将共享模式说清楚,然后顺着把其他 AQS 相关的类 CyclicBarrier.Semaphore 的源码一起过一下. CountDownLatch CountDownLatch 这个类是比较典型的 AQS 的共享模式的使用,这是一个高频使用的类.使用方法在前面一篇文章中有介绍 并发编程(二)—— CountDownLatch.CyclicBarrier和Semaphore 使用例子 我们看下 Do

后端程序员之路 42、Semaphore

前面学习了Pthreads,了解了线程和线程同步,而同步这个东西,与信号量是密不可分的.下面讨论的主要是Pthreads里的semaphore.h,而不是sys/sem.h [Linux]线程同步之信号量同步 - 江南烟雨 - 博客频道 - CSDN.NEThttp://blog.csdn.net/xiajun07061225/article/details/8467853 # 基本结构和概念- sem_t 信号量- P(sv):如果sv的值大于零,就给它减1:如果它的值为零,就挂起该进程的执行

CountDownLatch 闭锁、Semaphore信号量、Barrier栅栏

同步工具类可以是任何一个对象.阻塞队列可以作为同步工具类,其他类型的同步工具类还包括信号量(Semaphore).栅栏(Barrier).以及闭锁(Latch). 所有的同步工具类都包含一些特定的结构化属性:它们封装了一些状态,这些状态将决定执行同步工具类的线程是继续执行还是等待,此外还提供了一些方法对状态进行操作,以及另一些方法用于高效地等待同步工具类进入到预期状态. 1.闭锁 闭锁是一种同步工具类,可以延迟线程进度直到其到达终止状态.闭锁的作用相当于一扇门:在闭锁到达结束状态之前,这扇门一直