zoukankan      html  css  js  c++  java
  • semaphore(信号量)使用说明

    例子:
         以一个停车场运作为例。为了简单起见,假设停车场只有三个车位,一开始三个车位都是空的。这时如果同时来了五辆车,看门人允许其中三辆不受阻碍的进入,然后放下车拦,剩下的车则必须在入口等待,此后来的车也都不得不在入口处等待。这时,有一辆车离开停车场,看门人得知后,打开车拦,放入一辆,如果又离开两辆,则又可以放入两辆,如此往复。
        在这个停车场系统中,车位是公共资源,每辆车好比一个线程,看门人起的就是信号量的作用。
         更进一步,信号量的特性如下:信号量是一个非负整数(车位数),所有通过它的线程(车辆)都会将该整数减一(通过它当然是为了使用资源),当该整数值为零时,所有试图通过它的线程都将处于等待状态。在信号量上我们定义两种操作: Wait(等待) 和 Release(释放)。 当一个线程调用Wait(等待)操作时,它要么通过然后将信号量减一,要么一直等下去,直到信号量大于一或超时。Release(释放)实际上是在信号量上执行加操作,对应于车辆离开停车场,该操作之所以叫做“释放”是因为加操作实际上是释放了由信号量守护的资源。
        
         Java并发库Semaphore 可以很轻松完成信号量控制,Semaphore可以控制某个资源可被同时访问的个数,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。
     
    代码示例:
         
     1 import java.util.concurrent.ExecutorService;
     2 import java.util.concurrent.Executors;
     3 import java.util.concurrent.Semaphore;
     4  
     5 public class SemaphoreTest {
     6         public static void main(String[] args) {
     7               ExecutorService service = Executors. newCachedThreadPool();
     8                final Semaphore sp = new Semaphore(3);
     9                for (int i = 0; i < 10; i++) {
    10                      Runnable runnable = new Runnable() {
    11                             public void run() {
    12                                    try {
    13                                          sp.acquire();
    14                                   } catch (InterruptedException e1) {
    15                                          e1.printStackTrace();
    16                                   }
    17                                   System. out.println("线程" + Thread.currentThread().getName() + "进入,当前已有" + (3 - sp.availablePermits()) + "个并发" );
    18                                    try {
    19                                          Thread. sleep((long) (Math. random() * 10000));
    20                                   } catch (InterruptedException e) {
    21                                          e.printStackTrace();
    22                                   }
    23                                   System. out.println("线程" + Thread.currentThread().getName() + "即将离开");
    24                                   sp.release();
    25  
    26                                    // 下面代码有时候执行不准确,因为其没有和上面的代码合成原子单元
    27                                    // availablePermits()指的是当前信号灯库中有多少个可以被使用
    28                                   System. out.println("线程" + Thread.currentThread().getName() + "已离开,当前已有" + (3 - sp.availablePermits()) + "个并发" );
    29                            }
    30                      };
    31                      service.execute(runnable);
    32               }
    33        }
    34  
    35 }
  • 相关阅读:
    20180530
    vue路由配置出错,导致页面跳转会有闪屏问题
    20180528
    vuecli+ivew项目搭建
    centos6安装mysql
    华为云服务ESC
    centos6安装nginx
    国产操作系统aarch64编译filebeat
    Python常见问题
    Git
  • 原文地址:https://www.cnblogs.com/tstd/p/4999799.html
Copyright © 2011-2022 走看看