载请注明出处: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. python常用模块(2)

    之前学了两个常用的模块collections和re模块今天我们接着学习其他几个常用模块.都是比较常用的之前的学习或多或少也有所接触比如说时间模块等. 预习: 写一个验证码 首先 要有数字 其次 要有字 ...

  2. 1 Acid burn ★ Nag,Name/Serial,Serial

    无花无壳爆破 仅允许非商业转载,转载请注明出处

  3. BPM与OA的区别及联系

    BPM与OA的区别及联系 近年来,在企业管理信息系统一些名词反复被提及,然而外行人对于这些名词则是一头雾水,网上的解释又鱼龙混杂,没有绝对权威的文献可供参考,因此也就让我们对这些名词的认识越来越模糊. ...

  4. PHP程序中的文件锁、互斥锁、读写锁使用技巧解析

    文件锁全名叫 advisory file lock, 书中有提及. 这类锁比较常见,例如 mysql, php-fpm 启动之后都会有一个pid文件记录了进程id,这个文件就是文件锁. 这个锁可以防止 ...

  5. 升级项目到.NET Core 2.0,在Linux上安装Docker,并成功部署

    概述 容器,顾名思义是用来存放并容纳东西的器皿: 而容器技术伴着Docker的兴起也渐渐的映入大家的眼帘,它是一个抽象的概念,同时也是默默存在世上多年的技术,不仅能使应用程序间完全的隔离,而且还能在共 ...

  6. Python实现登录接口

    要求: 输入用户名和密码 认证成功,显示欢迎信息 用户名3次输入错误后,退出程序 密码3次输入错误后,锁定用户名 Readme: UserList.txt 是存放用户名和密码的文件,格式为:usern ...

  7. 英文面试&笔试

    Topics:1.Talk about your carreer plan2.In ten years, what kind of people you will be? At that time,w ...

  8. virtual与static

    virtual与static不能同时作用于一个函数.根据面向对象的理论,virtual的成员函数是可以变子类覆盖的,是实现多态的重要手段.而static作用的成员函数表示该函数仅属于某个类. 下面是实 ...

  9. 静态TLS和动态TLS

    静态TLS的使用方法: #include <Windows.h> #include <iostream> #include <iomanip> using name ...

  10. JavaJavaScript小问题系列之JSON解析

    1.错误消息及截图 这个很搞笑也很纠结,今天一开发妹子,发现一个问题: 服务端返回字符串"{\"phone\":\"15000000000\"}&qu ...