zoukankan      html  css  js  c++  java
  • java多线程-Semaphore信号量使用

    • 介绍

      信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们能够正确、合理的使用公共资源。

    • 概念

      Semaphore分为单值和多值两种,前者只能被一个线程获得,后者可以被若干个线程获得。

      Semaphore当前在多线程环境下被扩放使用,操作系统的信号量是个很重要的概念,在进程控制方面都有应用。Java并发库Semaphore 可以很轻松完成信号量控制,Semaphore可以控制某个资源可被同时访问的个数,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。比如在Windows下可以设置共享文件的最大客户端访问个数。

      单个信号量的Semaphore对象可以实现互斥锁的功能,并且可以是由一个线程获得了“锁”,再由另一个线程释放“锁”,这可应用于死锁恢复的一些场合。

    • 实例

      现在有一个三个信号灯,启动10个线程分别获取信号灯,当信号灯被占用时,其他线程只能等待,当信号灯被释放则等待线程获取信号灯。

      

     1 public class SemaphoreTest {
     2     public static void main(String[] args) {
     3         ExecutorService pool =  Executors.newCachedThreadPool();
     4         final Semaphore semaphore = new Semaphore(3,true);
     5         
     6         for (int i = 0; i < 10; i++) {
     7             Runnable runnable = new Runnable() {
     8                 @Override
     9                 public void run() {
    10                     try {
    11                         semaphore.acquire();//获取信号灯许可
    12                     } catch (InterruptedException e) {
    13                         // TODO Auto-generated catch block
    14                         e.printStackTrace();
    15                     }
    16                     System.out.println("Thread "+Thread.currentThread().getName()+" 进入" +"当前系统的并发数是:"+(3-semaphore.availablePermits()));
    17                     try {
    18                         Thread.sleep(new Random().nextInt(1000));
    19                     } catch (InterruptedException e) {
    20                         // TODO Auto-generated catch block
    21                         e.printStackTrace();
    22                     }
    23                     System.out.println("Thread "+Thread.currentThread().getName()+" 即将离开");
    24                     semaphore.release();//释放信号灯
    25                     System.out.println("Thread "+Thread.currentThread().getName()+" 已经离开,当前系统的并发数是:"+(3-semaphore.availablePermits()));
    26                 }
    27             };
    28             pool.execute(runnable);
    29         
    30         }
    31     }
    32 }

      另外需要注意的一点是,信号灯可以由一个线程使用,然后由另一个线程来进行释放,而锁只能由同一个线程启动和释放,不然就好发生死锁,这一点需要格外注意。

  • 相关阅读:
    noi放苹果
    二分 网线主管
    hdu 1421 dp
    hdu 1087 最大上升子序列的和(dp或线段树)
    快速排序+查找
    zoj 1425 最大交叉匹配
    hdu 3501 容斥原理或欧拉函数
    hdu 4671 异面直线的距离
    hdu 3320 计算几何(三维图形几何变换)
    hdu 2857 点在直线上的投影+直线的交点
  • 原文地址:https://www.cnblogs.com/lcngu/p/5215188.html
Copyright © 2011-2022 走看看