2019独角兽企业重金招聘Python工程师标准>>>

Semaphore是一个二进制信号量,只有0和1两个值。如果线程想要访问一个共享资源,它必须先获得信号量。如果信号量的内部计数器大于0,那么信号量减1,并允许访问这个资源。否则,如果信号量计数器等于0,线程会等待直至计数器大于0。

所以说计数器大于0,说明有资源可用。计数器等于0,说明没有资源可用。

同时Semaphore提供了一个带有boolean参数的构造方法,true代表公平锁,false代表非公平锁,默认实现是非公平锁。

我们使用Semaphore信号量来重写PrintQueue的例子。

首先实现一个PrintQueue打印队列,有一个Semaphore信号量用来并发访问控制。打印之前使用acquire()方法获取信号量,执行完毕后使用release()方法释放信号量。每次打印等待一个随机时间,模拟打印耗时。

public class PrintQueue {private Semaphore semaphore;public PrintQueue() {//semaphore = new Semaphore(1);   //非公平的semaphore = new Semaphore(1, true); //公平的}public void printJob(Object document) {try {semaphore.acquire();long duration = (long)(Math.random() * 10000);System.out.printf("%s: Print a job duration %d seconds.\n",Thread.currentThread().getName(), duration / 1000);Thread.sleep(duration);} catch (InterruptedException e) {e.printStackTrace();} finally {semaphore.release();}}
}

创建Job线程类,模拟打印请求。

public class Job implements Runnable{private PrintQueue printQueue;public Job(PrintQueue printQueue) {this.printQueue = printQueue;}@Overridepublic void run() {System.out.printf("%s: Going to print a Job.\n", Thread.currentThread().getName());printQueue.printJob(new Object());System.out.printf("%s: The Job has been printed.\n", Thread.currentThread().getName());}
}

主方法类中启动10个打印Job线程。

public class Main {public static void main(String[] args) {PrintQueue printQueue = new PrintQueue();Thread[] threads = new Thread[10];for (int i = 1; i < 10; i++) {threads[i] = new Thread(new Job(printQueue));}for (int i = 1; i < 10; i++) {threads[i].start();}}
}

查看日志,每次只有一个打印Job可以执行打印程序,其他线程处于WAITING状态。

Thread-0: Going to print a Job.
Thread-8: Going to print a Job.
Thread-7: Going to print a Job.
Thread-6: Going to print a Job.
Thread-5: Going to print a Job.
Thread-4: Going to print a Job.
Thread-0: Print a job duration 2 seconds.
Thread-3: Going to print a Job.
Thread-2: Going to print a Job.
Thread-1: Going to print a Job.
Thread-0: The Job has been printed.
Thread-8: Print a job duration 8 seconds.
Thread-8: The Job has been printed.
Thread-7: Print a job duration 8 seconds.
Thread-7: The Job has been printed.
Thread-6: Print a job duration 9 seconds.
Thread-6: The Job has been printed.
Thread-5: Print a job duration 6 seconds.
Thread-5: The Job has been printed.
Thread-4: Print a job duration 7 seconds.
Thread-4: The Job has been printed.
Thread-3: Print a job duration 4 seconds.
Thread-3: The Job has been printed.
Thread-2: Print a job duration 1 seconds.
Thread-2: The Job has been printed.
Thread-1: Print a job duration 1 seconds.
Thread-1: The Job has been printed.

转载于:https://my.oschina.net/nenusoul/blog/794378

Java并发编程中级篇(一):使用Semaphore信号量进行并发控制相关推荐

  1. Java并发编程中级篇(二):使用Semaphore信号量进行多个资源并发控制

    2019独角兽企业重金招聘Python工程师标准>>> 上一节中我们使用了Semaphore信号量保护共享资源,但是它只能保护一个共享资源,当我们需要同时保护多个共享资源的时候,我们 ...

  2. Java并发编程|第二篇:线程生命周期

    文章目录 系列文章 1.线程的状态 2.线程生命周期 3.状态测试代码 4.线程终止 4.1 线程执行完成 4.2 interrupt 5.线程复位 5.1interrupted 5.2抛出异常 6. ...

  3. java并发编程入门_探讨一下!Java并发编程基础篇一

    Java并发编程想必大家都不陌生,它是实现高并发/高流量的基础,今天我们就来一起学习这方面的内容. 什么是线程?什么是进程?他们之间有什么联系? 简单来说,进程就是程序的一次执行过程,它是系统进行资源 ...

  4. java控制并发数量_Java并发编程中级篇(二):使用Semaphore信号量进行多个资源并发控制...

    上一节中我们使用了Semaphore信号量保护共享资源,但是它只能保护一个共享资源,当我们需要同时保护多个共享资源的时候,我们只需要在创建信号量的时候使用new Semaphore(int)构造方法, ...

  5. Java并发编程高级篇(八):在执行器中取消任务

    2019独角兽企业重金招聘Python工程师标准>>> 前面我们已经学习如何把任务发送给执行器去执行,但是当我们想要取消一个已经发送给执行器的任务该怎么办呢.可以使用Future对象 ...

  6. Java并发编程高级篇(十):分离任务的执行和结果的处理

    2019独角兽企业重金招聘Python工程师标准>>> 在之前的例子中,我们使用执行器框架都是在主类中提交任务,等待任务执行完毕后再去处理任务执行的结果.接下来我们打算将任务的提交和 ...

  7. 将指定的计数添加到信号量中会导致其超过_并发编程用不上?Semaphore信号量了解一下...

    什么是信号量 Java中的同步工具类信号量即计数信号量(Counting Semaphore),是用来控制访问某个特定资源的操作数量,或同时执行某个指定操作的数量.可以简单理解为信号量用来限制对某个资 ...

  8. 《Java并发编程之美》

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yAwEsYPZ-1661534116043)(img/\1625573175405.jpg)] [外链图片转存失败,源站 ...

  9. 《Java并发编程之美》阅读笔记

    简介 最近在阅读<Java并发编程之美>这本书,为了督促自己啃完这本书,计划每读完一章写一篇阅读笔记,供以后参考. 笔记列表 第一部分 Java并发编程基础篇 第1章 并发编程线程基础 第 ...

最新文章

  1. java线程安全的set_Java并发编程之set集合的线程安全类你知道吗
  2. ThinkingInJava_3
  3. 基于最优化方法的超宽带通信信号设计
  4. MongoDB常用的操作命令(转)
  5. android垂直排列元素_Android弹性布局(FlexboxLayout)
  6. Python 程序开发90个注意事项
  7. 重磅 | 19 页花书精髓笔记!你可能正需要这份知识清单
  8. 计算机技术会议排名,计算机学科会议排名
  9. 是什么包_包粽子教程,喜欢的收藏,以后想吃什么样的都可以自己包
  10. django返回指定html文件,Django返回HTML文件的实现方法
  11. 加载的图片还会有未来吗?
  12. c++ 正则表达式_Java入门 - 语言基础 - 18.正则表达式
  13. 我的第一本算法书(图解算法)——什么是哈希表
  14. 解析RocketMQ的消息索引文件consumequeue
  15. paip.版本控制CVS-SVN-TFS总结
  16. Coverage [minx,miny,maxx,maxy] is [12, 4, 13, 6, 3], index [x,y,z] is [2, 5, 3]错误原因及其解决方式...
  17. 修改自己电脑连接的路由器的配置网址192.168.1.1
  18. 80C51单片机复习资料(一)
  19. 检查计算机电源,如何检测电脑电源的状况
  20. (SQL语句)查询排序,顺序和倒序

热门文章

  1. 四门专业课,有点困难哈~
  2. The request failed with HTTP status 401:Access Denied
  3. hdu1007 最近点对
  4. 【错误记录】Visual Studio 中配置 NDK 头文件路径
  5. 【错误记录】Android Studio 编译时 Kotlin 代码编译报错 ( Not enough information to infer type variable T )
  6. 【MATLAB】矩阵操作 ( 矩阵下标 | 矩阵下标排列规则 )
  7. 【Android RTMP】音频数据采集编码 ( FAAC 音频编码参数设置 | FAAC 编码器创建 | 获取编码器参数 | 设置 AAC 编码规格 | 设置编码器输入输出参数 )
  8. 【Netty】Netty 核心组件 ( ChannelPipeline 中的 ChannelHandlerContext 双向链表分析 )
  9. luogu P1199 【三国游戏】
  10. springBoot静态资源处理