并发编程之信号量

并发编程之信号量

详解

1、Semaphore可以控同时访问的线程个数

2、Semaphore类位于java.util.concurrent包下,它提供了2个构造器:

12345678

//参数permits表示许可数目,即同时可以允许多少线程进行访问public Semaphore(int permits) { sync = new NonfairSync(permits);}//这个多了一个参数fair表示是否是公平的,即等待时间越久的越先获取许可public Semaphore(int permits, boolean fair) { sync = (fair)? new FairSync(permits) : new NonfairSync(permits);}

3、重要方法,acquire()、release()方法:

  • acquire()用来获取一个许可,若无许可能够获得,则会一直等待,直到获得许可
  • release()用来释放许可。注意,在释放许可之前,必须先获获得许可
  • 这4个方法都会被阻塞

1234

public void acquire() throws InterruptedException { } //获取一个许可public void acquire(int permits) throws InterruptedException { } //获取permits个许可public void release() { } //释放一个许可public void release(int permits) { } //释放permits个许可

  • 不阻塞的方法如下:

12345678

//尝试获取一个许可,若获取成功,则立即返回true,若获取失败,则立即返回falsepublic boolean tryAcquire() { }; //尝试获取一个许可,若在指定的时间内获取成功,则立即返回true,否则则立即返回falsepublic boolean tryAcquire(long timeout, TimeUnit unit) throws InterruptedException { }; //尝试获取permits个许可,若获取成功,则立即返回true,若获取失败,则立即返回falsepublic boolean tryAcquire(int permits) { }; //尝试获取permits个许可,若在指定的时间内获取成功,则立即返回true,否则则立即返回falsepublic boolean tryAcquire(int permits, long timeout, TimeUnit unit) throws InterruptedException { };

  • 通过availablePermits()方法得到可用的许可数目

举例

  • 我们知道读锁可以允许多个线程同时进行读取,我们可以使用信号量来限制线程个数,如下

12345678910111213141516171819202122232425262728293031323334

public class TestSemaphore { private static final Semaphore semaphore=new Semaphore(5,true); //创建5个信号量同时用与读文件 private static final ReentrantReadWriteLock rwLock= new ReentrantReadWriteLock(); private static final Lock rLock=rwLock.readLock(); //获取读锁 public static void main(String[] args) { //执行10个线程,通过信号量控制,只能5个线程5个线程的执行 for (int i = 0; i < 10; i++) { MyThread thread=new MyThread(); thread.setName("线程"+(i+1)); thread.start(); } } static class MyThread extends Thread{ @Override public void run() { reader(); } //读方法 public void reader(){ rLock.lock(); //获取读锁 try { semaphore.acquire(); //获取信号量,信号量-1,如果没有成功获取,那么阻塞 System.out.println(this.getName()+"正在读文件"); Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); }finally{ semaphore.release(); //释放信号量 rLock.unlock(); //释放锁 } } }}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏猿天地

高性能NIO框架Netty-对象传输

上篇文章高性能NIO框架Netty入门篇我们对Netty做了一个简单的介绍,并且写了一个入门的Demo,客户端往服务端发送一个字符串的消息,服务端回复一个字符串...

3108
来自专栏杨建荣的学习笔记

关于正则表达式第四篇(r3笔记第53天)

正则表达式,林林总总说了几篇,还是有不少的内容需要补充。 -->星号 字符出现0次或者多次 $ echo "ik"|sed -n '/e*/p' ik $ e...

27712
来自专栏闻道于事

SpringMVC 常用注解

1、@Controller      @Controller 用于标记在一个类上,使用它标记的类就是一个SpringMVC Controller 对象。分发处理...

2996
来自专栏Hongten

python开发_pprint()

1094
来自专栏开发与安全

linux网络编程之POSIX 共享内存和 系列函数

在前面介绍了system v 共享内存的相关知识,现在来稍微看看posix 共享内存 和系列函数。 共享内存简单来说就是一块真正的物理内存区域,可以使用一些函数...

2190
来自专栏微信公众号:Java团长

自己手写一个SpringMVC框架

前端框架很多,但没有一个框架称霸,后端框架现在Spring已经完成大一统。所以学习Spring是Java程序员的必修课。

942
来自专栏微信公众号:Java团长

SpringMVC常用注解标签详解

在SpringMVC 中,控制器Controller 负责处理由DispatcherServlet 分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一...

1462
来自专栏javathings

@Async 注解的使用

在 Spring 中,@Async 标注的方法,在执行的时候,是异步运行的,它运行在独立的线程中,程序不会被该方法所阻塞。

1.1K2
来自专栏为数不多的Android技巧

Android插件化原理解析——Hook机制之动态代理

使用代理机制进行API Hook进而达到方法增强是框架的常用手段,比如J2EE框架Spring通过动态代理优雅地实现了AOP编程,极大地提升了Web开发效率;同...

1162
来自专栏IT笔记

Grafana+Prometheus系统监控之SpringBoot

前言 前一段时间使用SpringBoot创建了一个webhook项目,由于近期项目中也使用了不少SpringBoot相关的项目,趁着周末,配置一下使用prome...

1.4K6

扫码关注云+社区

领取腾讯云代金券