Java中的信号量Semaphore

in 编程
关注公众号【好便宜】( ID:haopianyi222 ),领红包啦~
阿里云,国内最大的云服务商,注册就送数千元优惠券:https://t.cn/AiQe5A0g
腾讯云,良心云,价格优惠: https://t.cn/AieHwwKl
搬瓦工,CN2 GIA 优质线路,搭梯子、海外建站推荐: https://t.cn/AieHwfX9

信号量的实现模型一般包括:1个计数器、1个等待队列、3个方法(需要保证原子性)

Semaphore 实现的伪代码(JDK 中 Semaphore 是基于 AbstractQueuedSynchronizer 实现,可以指定是否公平):

class Semaphore{
	//计数器
	int count;
	
	//等待队列
	Queue queue;
	
	//初始化
	Semaphore(int c){
		this.count=c;
	}
	
	//获取许可证
	void acquire(){
		count--;
		if(count<0){
			//将当前线程插入等待队列
			//阻塞当前线程
		}
	}
	
	//获取许可证
	void release(){
		count++;
		if(count<=0) {
			//移除等待队列中的某个线程
			//唤醒某个线程
		}
	}
}

 

使用信号量实现互斥锁效果:

package constxiong.interview;

import java.util.concurrent.Semaphore;

/**
 * 测试使用信号量实现锁的效果
 * @author ConstXiong
 * @date 2019-12-18 14:18:47
 */
public class TestSemaphore {

	private static int count;
	
	private static Semaphore semaphore = new Semaphore(1); 
	
	public static void main(String[] args) {
		for (int i = 0; i < 100; i++) {
			new Thread(() -> {
				add();
				System.out.println(count);
			}).start();
		}
	}
	
	private static void add() {
		try {
			semaphore.acquire();
			Thread.sleep(100);
			count++;
		} catch(InterruptedException e) {
			e.printStackTrace();
		} finally {
			semaphore.release();
		}
	}
	
}

 

除了能实现互斥锁,信号量还可以做到允许多个线程访问同一个临界区,这是它与互斥锁一个较大的区别点。

将代码进行修改,实现限流功能:

package constxiong.interview;

import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 测试使用信号量实现限流的效果
 * @author ConstXiong
 * @date 2019-12-18 14:18:47
 */
public class TestSemaphore {
	
	private static AtomicInteger acount = new AtomicInteger(0);
	
	private static Semaphore semaphore = new Semaphore(10); 
	
	public static void main(String[] args) {
		testAddAtomic();
	}
	
	/**
	 * 测试允许十个线程并发递增 acount
	 */
	private static void testAddAtomic() {
		for (int i = 0; i < 100; i++) {
			new Thread(() -> {
				System.out.println(addAtomic());
			}).start();
		}
	}
	
	private static int addAtomic() {
		try {
			semaphore.acquire();
			Thread.sleep(100);
			return acount.incrementAndGet();
		} catch(InterruptedException e) {
			e.printStackTrace();
		} finally {
			semaphore.release();
		}
		return -1;
	}
	
}

 

在实际的 Java 开发中,信号量的使用相对互斥锁来说较少,知名度没那么高,但在其他编程语言中使用较广。


原文链接
 


 

 

关注公众号【好便宜】( ID:haopianyi222 ),领红包啦~
阿里云,国内最大的云服务商,注册就送数千元优惠券:https://t.cn/AiQe5A0g
腾讯云,良心云,价格优惠: https://t.cn/AieHwwKl
搬瓦工,CN2 GIA 优质线路,搭梯子、海外建站推荐: https://t.cn/AieHwfX9
扫一扫关注公众号添加购物返利助手,领红包
Comments are closed.

推荐使用阿里云服务器

超多优惠券

服务器最低一折,一年不到100!

朕已阅去看看