载请注明出处:http://blog.csdn.net/ns_code/article/details/17524153



操作系统中,信号量是个很重要的概念,它在控制进程间的协作方面有着非常重要的作用,通过对信号量的不同操作,可以分别实现进程间的互斥与同步。当然它也可以用于多线程的控制,我们完全可以通过使用信号量来自定义实现类似Java中的synchronized、wait、notify机制。

Java并发包中的信号量Semaphore实际上是一个功能完毕的计数信号量,从概念上讲,它维护了一个许可集合,对控制一定资源的消费与回收有着很重要的意义。Semaphore可以控制某个资源被同时访问的任务数,它通过acquire()获取一个许可,release()释放一个许可。如果被同时访问的任务数已满,则其他acquire的任务进入等待状态,直到有一个任务被release掉,它才能得到许可。

下面给出一个采用Semaphore控制并发访问数量的示例程序:

  1. import java.util.concurrent.ExecutorService;
  2. import java.util.concurrent.Executors;
  3. import java.util.concurrent.Semaphore;
  4. public class SemaphoreTest{
  5. public static void main(String[] args) {
  6. //采用新特性来启动和管理线程——内部使用线程池
  7. ExecutorService exec = Executors.newCachedThreadPool();
  8. //只允许5个线程同时访问
  9. final Semaphore semp = new Semaphore(5);
  10. //模拟10个客户端访问
  11. for (int index = 0; index < 10; index++){
  12. final int num = index;
  13. Runnable run = new Runnable() {
  14. public void run() {
  15. try {
  16. //获取许可
  17. semp.acquire();
  18. System.out.println("线程" +
  19. Thread.currentThread().getName() + "获得许可:"  + num);
  20. //模拟耗时的任务
  21. for (int i = 0; i < 999999; i++) ;
  22. //释放许可
  23. semp.release();
  24. System.out.println("线程" +
  25. Thread.currentThread().getName() + "释放许可:"  + num);
  26. System.out.println("当前允许进入的任务个数:" +
  27. semp.availablePermits());
  28. }catch(InterruptedException e){
  29. e.printStackTrace();
  30. }
  31. }
  32. };
  33. exec.execute(run);
  34. }
  35. //关闭线程池
  36. exec.shutdown();
  37. }
  38. }

某次执行的结果如下:

线程pool-1-thread-1获得许可:0

线程pool-1-thread-1释放许可:0

当前允许进入的任务个数:5

线程pool-1-thread-2获得许可:1

线程pool-1-thread-6获得许可:5

线程pool-1-thread-4获得许可:3

线程pool-1-thread-8获得许可:7

线程pool-1-thread-2释放许可:1

当前允许进入的任务个数:2

线程pool-1-thread-5获得许可:4

线程pool-1-thread-8释放许可:7

线程pool-1-thread-3获得许可:2

线程pool-1-thread-4释放许可:3

线程pool-1-thread-10获得许可:9

线程pool-1-thread-6释放许可:5

线程pool-1-thread-10释放许可:9

当前允许进入的任务个数:2

线程pool-1-thread-3释放许可:2

当前允许进入的任务个数:1

线程pool-1-thread-5释放许可:4

当前允许进入的任务个数:3

线程pool-1-thread-7获得许可:6

线程pool-1-thread-9获得许可:8

线程pool-1-thread-7释放许可:6

当前允许进入的任务个数:5

当前允许进入的任务个数:3

当前允许进入的任务个数:3

当前允许进入的任务个数:3

线程pool-1-thread-9释放许可:8

当前允许进入的任务个数:5

可以看出,Semaphore允许并发访问的任务数一直为5,当然,这里还很容易看出一点,就是Semaphore仅仅是对资源的并发访问的任务数进行监控,而不会保证线程安全,因此,在访问的时候,要自己控制线程的安全访问。

转:【Java并发编程】之二十三:并发新特性—信号量Semaphore(含代码)的更多相关文章

  1. 转: 【Java并发编程】之十三:生产者—消费者模型(含代码)

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/17249321 生产者消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一 ...

  2. 并发编程(二)—— CountDownLatch、CyclicBarrier和Semaphore

    本文将讲解CountDownLatch,CyclicBarrier和Semaphore这三个并发包里面的辅助类. CountDownLatch 正如每个Java文档所描述的那样,CountDownLa ...

  3. 【Java并发编程】:并发新特性—信号量Semaphore

    在操作系统中,信号量是个很重要的概念,它在控制进程间的协作方面有着非常重要的作用,通过对信号量的不同操作,可以分别实现进程间的互斥与同步.当然它也可以用于多线程的控制,我们完全可以通过使用信号量来自定 ...

  4. java并发编程(二十三)----(JUC集合)ConcurrentSkipListMap介绍

    ConcurrentSkipListMap提供了一种线程安全的并发访问的排序映射表.内部是SkipList(跳表)结构实现,在理论上能够在O(log(n))时间内完成查找.插入.删除操作. 理解Ski ...

  5. 并发编程(二)------并发类容器ConcurrentMap

    并发类容器: jdk5.0以后提供了多种并发类容器来替代同步类容器从而改善性能. 同步类容器的状态都是串行化的. 他们虽然实现了线程安全,但是严重降低了并发性,在多线程环境时,严重降低了应用程序的吞吐 ...

  6. [Java并发编程(二)] 线程池 FixedThreadPool、CachedThreadPool、ForkJoinPool?为后台任务选择合适的 Java executors

    [Java并发编程(二)] 线程池 FixedThreadPool.CachedThreadPool.ForkJoinPool?为后台任务选择合适的 Java executors ... 摘要 Jav ...

  7. 并发编程(二)concurrent 工具类

    并发编程(二)concurrent 工具类 一.CountDownLatch 经常用于监听某些初始化操作,等初始化执行完毕后,通知主线程继续工作. import java.util.concurren ...

  8. Pthread 并发编程(二)——自底向上深入理解线程

    Pthread 并发编程(二)--自底向上深入理解线程 前言 在本篇文章当中主要给大家介绍线程最基本的组成元素,以及在 pthread 当中给我们提供的一些线程的基本机制,因为很多语言的线程机制就是建 ...

  9. Java并发编程入门与高并发面试(三):线程安全性-原子性-CAS(CAS的ABA问题)

    摘要:本文介绍线程的安全性,原子性,java.lang.Number包下的类与CAS操作,synchronized锁,和原子性操作各方法间的对比. 线程安全性 线程安全? 线程安全性? 原子性 Ato ...

随机推荐

  1. 使用Travis CI自动部署Hexo博客

    自从使用GitHub Pages和Hexo来发布博客之后,不得不说方便了许多,只需要几个简单的命令博客就发布了.但在不断的使用中发现每次的发布操作也挺耗时的. 我一般的操作是将平时整理好的md文件放到 ...

  2. 利用Java随机,生成随机学生数据

    为模拟向数据库中大量插入学生数据(注:此处应该用PreparedStatement.batchUpdate等批处理提高效率)的情形,通过Java随机来生成学生数据. 一.要生成的学生数据 studen ...

  3. Jmeter==HTTP信息头管理器的作用

    HTTP信息头管理器在Jmeter的使用过程中起着很重要的作用,通常我们在通过Jmeter向服务器发送http请求(get或者post)的时候,往往后端需要一些验证信息,比如说web服务器需要带过去c ...

  4. 2017年最重要的HTML5开发手册,传播正能量

    今天给大家推荐这个HTML5开发手册,希望能帮助正在学习web前端的人,鄙人也是刚学习前端没多久,借助于一点资讯平台能够结识更多前端大牛,这是我的HTML5进阶学习一点资讯群:250777811,里面 ...

  5. 计蒜客模拟赛D2T1 蒜头君的兔子:矩阵快速幂

    题目链接:https://nanti.jisuanke.com/t/16442 题意: 有个人在第一年送了你一对1岁的兔子.这种兔子刚生下来的时候算0岁,当它在2~10岁的时候,每年都会生下一对兔子, ...

  6. HTML中直接写js 函数

    1.在HTML中直接写JS函数: <body onload="javascript:{window.location.href='http://www.baidu.com/'}&quo ...

  7. C++构造函数初始化列表与赋值

    C++中类的初始化操作一般有四个部分组成: 1.构造函数初始化列表 2.构造函数体内赋值 3.类外部初始化 4.类声明时直接赋值 对于内部数据类型(char,int,float...),构造函数初始化 ...

  8. 剑指OFFER的跳台阶问题

    一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法. (斐波那契数列的变形) F(1)=1;F(2)=2; F(n)=F(n-1)+F(n-2); class S ...

  9. Servlet 服务器端小程序

    1.tomcat安装及目录介绍 JAVA_HOME CATALINA_HOME PATH=%JAVA_HOME%/bin;2.静态web项目.动态web项目 WEB-INF lib classes w ...

  10. Ngnix+tomcat负载均衡

    系统环境 Centos6.5 nginx1.4.7  https://nginx.org/download/nginx-1.4.7.tar.gz tomcat7.0.79 http://apache. ...