`

并发编程回顾:信号量Semaphore

 
阅读更多

原先多线程并发编程的学习笔记和代码整理一下贴上来。

---------------------------------

信号量Semaphore

根据JDK文档描述:

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

个人理解为定义一个信号量同时指定它的许可数量,acquire时许可+1,release时许可-1。如果到达最大许可数时,后面的线程会阻塞。

一个简单的示例:

定义一个打印资源id的任务。该任务在运行前先获取信号量的一个许可,运行完后会释放该许可。

class ResourceInfo implements Runnable{
	private final int resId;
	private Semaphore semaphore;
	public ResourceInfo(int rid,Semaphore semp){
		this.semaphore=semp;
		resId=rid;
	}
	@Override
	public void run() {
		try{
			semaphore.acquire();
			System.out.println("resId:"+resId);
			Thread.sleep((long) (Math.random() * 10000));  
			semaphore.release();
		}catch(InterruptedException e){
			e.printStackTrace();
		}
	}
}
然后使用信号量:
ExecutorService exec = Executors.newCachedThreadPool();
Semaphore semap=new Semaphore(10);
for(int i=0;i<20;i++){
	exec.execute(new ResourceInfo(i, semap));
}
exec.shutdown();

这里定义了一个信号量,最多允许10个任务获取许可,然后一次启动20个任务。运行结果如下:

resId:0
resId:2
resId:1
resId:3
resId:5
resId:6
resId:4
resId:7
resId:8
resId:9
resId:10
resId:11
resId:13
resId:12
resId:14
resId:16
resId:15
resId:17
resId:19
resId:18

前10个任务获取到许可后,后面的10个任务会阻塞,直到前面的任务释放许可。这里我们修改一下:

Semaphore semap=new Semaphore(10,true);

指定公平设置(默认为false):如果此信号量保证在争用时按先进先出的顺序授予许可,则为 true;否则为 false。再运行一下看看:

resId:0
resId:3
resId:2
resId:1
resId:4
resId:5
resId:7
resId:6
resId:8
resId:9
resId:10
resId:11
resId:12
resId:13
resId:14
resId:15
resId:16
resId:17
resId:18
resId:19

公平设置后,被阻塞的线程就会按照先进先出的顺序获得许可,因此,后面10个线程是顺序打印Id信息的。

 

分享到:
评论

相关推荐

    C++面向对象多线程编程1-8

    为了防止数据竞争和死锁,C++提供了多种工具,如互斥量(`std::mutex`)、条件变量(`std::condition_variable`)、信号量(`std::semaphore`)等。互斥量用于保护共享资源,确保同一时间只有一个线程能访问;条件...

    Visual.C.网络高级编程3

    常见的同步机制包括互斥量(Mutex)、信号量(Semaphore)、条件变量(Condition Variable)等。 - **多线程服务器**:服务器端可以为每个客户端连接创建一个独立的线程,从而实现并发处理。 ##### 3. 高级网络编程...

    JAVA项目_坦克大战网络版视频教程.rar

    JAVA提供了多种并发工具,如Semaphore(信号量)、ReentrantLock(可重入锁)等,用于控制对共享资源的访问。 5. **游戏逻辑**:坦克大战的规则和算法设计是项目的关键。你需要理解游戏的逻辑,如坦克移动规则、...

    C# 多线程 应用程序 实例 程序 说明文件

    - 实践并发编程,包括异步编程模型,如async/await关键字,以及Task类的使用。 - 分析和解决多线程环境下可能出现的问题,如线程安全和性能优化。 通过研究这些实例和文档,开发者不仅能提升自己的C#编程能力,还能...

    java源码大全

    - **并发工具类**:如Semaphore(信号量)、CyclicBarrier(回环栅栏)、CountDownLatch(倒计时 latch)等,它们提供了更高级的线程同步机制。 3. **Java 基础**: - **基本数据类型**:Java有8种基本数据类型,...

    Python开启线程,在函数中开线程的实例

    self.__sem = threading.Semaphore(value=5) # 初始化信号量,最大并发数为5 def handle(self, data): # 开启线程,传入参数 _thread = threading.Thread(target=self.__run, args=(data,)) _thread....

    基于Java回顾之多线程同步的使用详解

    6. **信号量Semaphore**:可以限制同时访问特定资源的线程数量,常用于限流或同步。 7. **CountDownLatch**:用于协调多个线程,让它们等待其他线程完成后再继续执行。 8. **CyclicBarrier**:允许一组线程等待...

    基于一个应用程序多线程误用的分析详解

    例如,可以通过事件、条件变量或信号量来实现。 7. **资源释放**: 确保在所有操作完成后正确地释放资源,如关闭网络连接。不正确的资源释放可能导致资源泄漏,影响应用程序的长期运行。 总结来说,多线程误用...

    java加强笔记

    - `Semaphore`是一种计数信号量,可以控制多个线程对共享资源的访问。 ##### 15. Java5的CyclicBarrier同步工具 - `CyclicBarrier`可以实现线程间的屏障同步。 ##### 16. Java5的CountDownLatch同步工具 - `...

Global site tag (gtag.js) - Google Analytics