JDK1.5 Semaphore实例

news/2024/7/8 4:36:00 标签: java, java多线程, thread, Semaphore

Semaphore

       一个计数信号量。从概念上讲,信号量维护了一个许可集合。如有必要,在许可可用前会阻塞每一个 acquire(),然后再获取该许可。每个 release() 添加一个许可,从而可能释放一个正在阻塞的获取者。但是,不使用实际的许可对象,Semaphore 只对可用许可的号码进行计数,并采取相应的行动。

Semaphore 通常用于限制可以访问某些资源(物理或逻辑的)的线程数目。

       获得一项前,每个线程必须从信号量获取许可,从而保证可以使用该项。该线程结束后,将项返回到池中并将许可返回到该信号量,从而允许其他线程获取该项。注意,调用 acquire() 时无法保持同步锁定,因为这会阻止将项返回到池中。信号量封装所需的同步,以限制对池的访问,这同维持该池本身一致性所需的同步是分开的。

将信号量初始化为 1,使得它在使用时最多只有一个可用的许可,从而可用作一个相互排斥的锁。这通常也称为二进制信号量,因为它只能有两种状态:一个可用的许可,或零个可用的许可。按此方式使用时,二进制信号量具有某种属性(与很多 Lock 实现不同),即可以由线程释放锁定,而不是由所有者(因为信号量没有所有权的概念)。在某些专门的上下文(如死锁恢复)中这会很有用。

       构造方法:

a.       Semaphore(int permits):用给定的许可数和非公平的公平设置创建一个 Semaphore

b.       Semaphore(int permits, boolean fair):用给定的许可数和给定的公平设置创建一个 Semaphore

 

实例:

java">package com.bijian.thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

public class Main {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		// 线程池
		ExecutorService exec = Executors.newCachedThreadPool();
		// 只能5个线程同时访问
		final Semaphore semp = new Semaphore(5);
		// 模拟20个客户端访问
		for (int index = 0; index < 20; index++) {
			final int NO = index;
			Runnable run = new Runnable() {
				public void run() {
					try {
						// 获取许可
						semp.acquire();
						System.out.println(Thread.currentThread().getName() + ": Accessing: " + NO);
						Thread.sleep((long) (Math.random() * 1000));
					} catch (InterruptedException e) {
						e.printStackTrace();
					} finally {
						// 访问完后,释放
						semp.release();
						System.out.println("-----------------" + semp.availablePermits());
					}
				}
			};
			exec.execute(run);
		}
		// 退出线程池
		exec.shutdown();
	}
}

 

运行结果:
pool-1-thread-1: Accessing: 0
pool-1-thread-4: Accessing: 3
pool-1-thread-3: Accessing: 2
pool-1-thread-2: Accessing: 1
pool-1-thread-6: Accessing: 5
-----------------1
pool-1-thread-8: Accessing: 7
-----------------1
pool-1-thread-7: Accessing: 6
-----------------1
pool-1-thread-9: Accessing: 8
-----------------1
pool-1-thread-10: Accessing: 9
-----------------1
pool-1-thread-5: Accessing: 4
-----------------1
pool-1-thread-11: Accessing: 10
-----------------1
pool-1-thread-12: Accessing: 11
-----------------1
pool-1-thread-13: Accessing: 12
-----------------1
pool-1-thread-14: Accessing: 13
-----------------1
pool-1-thread-15: Accessing: 14
-----------------1
pool-1-thread-16: Accessing: 15
-----------------1
pool-1-thread-17: Accessing: 16
-----------------1
pool-1-thread-18: Accessing: 17
-----------------1
pool-1-thread-19: Accessing: 18
-----------------1
pool-1-thread-20: Accessing: 19
-----------------1
-----------------2
-----------------3
-----------------4
-----------------5

 


http://www.niftyadmin.cn/n/1319087.html

相关文章

操作系统笔试题及答案

操作系统笔试题及答案&#xff08;一&#xff09; 在下列系统中&#xff0c;( )是实时系统。 A.计算机激光照排系统 B.航空定票系统 C&#xff0e;办公自动化系统 D.计算机辅助设计系统 答案&#xff1a;B 2&#xff0e;操作系统是一种( )。 A.应用软件 B&#xff0e;系统软件 …

Vue虚拟DOM是这样实现的

Vue虚拟DOM1.什么是虚拟DOM&#xff1f;2.为什么使用虚拟DOM3.Vue中的虚拟DOM4.VNode类的作用1.什么是虚拟DOM&#xff1f; 虚拟DOM就是通过一个JS对象来描述一个DOM节点&#xff0c;比如 <div class"a" id"b">我是内容</div> { tag:div, //…

JDK1.5 Queue

JDK1.5 Queue LinkedList&#xff1a; LinkedList不是同步的。如果多个线程同时访问列表&#xff0c;而其中至少一个线程从结构上修改了该列表&#xff0c;则它必须 保持外部同步。&#xff08;结构修改指添加或删除一个或多个元素的任何操作&#xff1b;仅设置元素的值不是结构…

Vue中的Diff算法实现过程

目录1.Diff的由来&#xff1f;2.如何实现&#xff1f;1.Diff的由来&#xff1f; Vue利用双向绑定原理&#xff0c;实现了视图层和数据层的同时更新&#xff0c;在数据层发生变化的时候利用虚拟DOM去更新对应的DOM树&#xff0c;那么新DOM树和旧DOM树如何去比对&#xff0c;DOM…

ASP.NET MVC 如何实现头压缩

网页的头部压缩在页面体积大的情况下非常有必要做&#xff0c;它会使页面体积有一个明显的减小&#xff0c;同时加到网页从服务端下载到客户端的速度&#xff0c;以下是我做的一个测试&#xff1a; 没有使用头压缩时&#xff1a; 使用了头压缩后&#xff1a; 我们可以看到&…

JDK1.5 生产消费者

ArrayBlockingQueue&#xff1a; 一个由数组支持的有界阻塞队列。此队列按 FIFO&#xff08;先进先出&#xff09;原则对元素进行排序。队列的头部 是在队列中存在时间最长的元素。队列的尾部 是在队列中存在时间最短的元素。新元素插入到队列的尾部&#xff0c;队列检索操作则…

什么是vue?如何理解双向数据绑定?Vue2.0和Vue3.0实现双向绑定的区别

1.何为Vue&#xff1f; Vue是一套用于构建单页面应用的JavaScript框架&#xff0c;它的核心采用MVVM框架进行搭建&#xff0c;自底向下增量开发&#xff0c;主要的特点就是实现了数据的双向绑定&#xff0c;通过渐进式的开发模式减小项目包体积&#xff0c;采用模块化开发的思…

WPF附加属性

1、定义&#xff1a;一个属性原来不属于某个对象&#xff0c;但由于某种需求而被后来附加上去。附加属性的本质是依赖属性。 2、作用&#xff1a;将属性与数据类型解耦&#xff0c;让数据类型的设计的更加灵活。 3、举例&#xff1a;Human&#xff0c;School。Human中的一个人&…