zoukankan      html  css  js  c++  java
  • Semaphore的使用

      Semaphore也是一个线程同步的辅助类,可以维护当前访问自身的线程个数,并提供了同步机制。使用Semaphore可以控制同时访问资源的线程个数,例如,实现一个文件允许的并发访问数。

    Semaphore的主要方法摘要:

      void acquire():从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断。

      void release():释放一个许可,将其返回给信号量。

      int availablePermits():返回此信号量中当前可用的许可数。

      boolean hasQueuedThreads():查询是否有线程正在等待获取。

    下面是一个例子:

     1 package com.thread;
     2 
     3 import java.util.concurrent.ExecutorService;
     4 import java.util.concurrent.Executors;
     5 import java.util.concurrent.Semaphore;
     6 
     7 public class SemaphoreTest {
     8     public static void main(String[] args) {
     9         ExecutorService service = Executors.newCachedThreadPool();
    10         final  Semaphore sp = new Semaphore(3);//创建Semaphore信号量,初始化许可大小为3
    11         for(int i=0;i<10;i++){
    12             try {
    13                 Thread.sleep(100);
    14             } catch (InterruptedException e2) {
    15                 e2.printStackTrace();
    16             }
    17             Runnable runnable = new Runnable(){
    18                     public void run(){
    19                     try {
    20                         sp.acquire();//请求获得许可,如果有可获得的许可则继续往下执行,许可数减1。否则进入阻塞状态
    21                     } catch (InterruptedException e1) {
    22                         e1.printStackTrace();
    23                     }
    24                     System.out.println("线程" + Thread.currentThread().getName() + 
    25                             "进入,当前已有" + (3-sp.availablePermits()) + "个并发");
    26                     try {
    27                         Thread.sleep((long)(Math.random()*10000));
    28                     } catch (InterruptedException e) {
    29                         e.printStackTrace();
    30                     }
    31                     System.out.println("线程" + Thread.currentThread().getName() + 
    32                             "即将离开");                    
    33                     sp.release();//释放许可,许可数加1
    34                     //下面代码有时候执行不准确,因为其没有和上面的代码合成原子单元
    35                     System.out.println("线程" + Thread.currentThread().getName() + 
    36                             "已离开,当前已有" + (3-sp.availablePermits()) + "个并发");                    
    37                 }
    38             };
    39             service.execute(runnable);            
    40         }
    41     }
    42 
    43 }
      
      单个信号量的Semaphore对象可以实现互斥锁的功能,并且可以是由一个线程获得了“锁”,再由另一个线程释放“锁”,这可应用于死锁恢复的一些场合。
     1 package com.thread;
     2 import java.util.concurrent.ExecutorService;
     3 import java.util.concurrent.Executors;
     4 import java.util.concurrent.Semaphore;
     5 import java.util.concurrent.locks.Lock;
     6 import java.util.concurrent.locks.ReentrantLock;
     7 
     8 public class LockTest {
     9     public static void main(String[] args) {
    10         final Business business = new Business();
    11         ExecutorService executor =  Executors.newFixedThreadPool(3);
    12         for(int i=0;i<3;i++)
    13         {
    14             executor.execute(
    15                     new Runnable()
    16                     {
    17                         public void run()
    18                         {
    19                             business.service();
    20                         }
    21                     }
    22             
    23             );
    24         }
    25         executor.shutdown();
    26     }
    27     
    28     private static class Business
    29     {
    30         private int count;
    31         Lock lock = new ReentrantLock();
    32         Semaphore sp = new Semaphore(1);
    33         public void service() 
    34         {
    35             //lock.lock();
    36             try {
    37                 sp.acquire(); //当前线程使用count变量的时候将其锁住,不允许其他线程访问
    38             } catch (InterruptedException e1) {
    39                 e1.printStackTrace();
    40             }
    41             try {
    42                 count++;
    43                 try {
    44                     Thread.sleep(1000);
    45                 } catch (InterruptedException e) {
    46                     e.printStackTrace();
    47                 }
    48                 System.out.println(count);
    49             } catch (RuntimeException e) {
    50                 e.printStackTrace();
    51             }
    52             finally
    53             {
    54                 //lock.unlock();
    55                 sp.release();  //释放锁
    56             }
    57         }
    58     }        
    59     
    60 }
  • 相关阅读:
    信用卡知识:自动扣款日不等于最后还款日_刷卡技巧_财经_腾讯网
    北京,大兴,采育,京福路边上。嘿嘿,交通还是很便利的。
    想知道:北京市 亦庄交通队在哪?
    bda_百度百科
    聚合服务资费标准
    公租自行车-北京经济技术开发区
    北京公共自行车-北京市交通委员会运输管理局
    北京公共自行车租赁方法_百度知道
    NEXT | 不错过任何一个新产品
    吸血鬼日记 第五季 16 | 美剧单词
  • 原文地址:https://www.cnblogs.com/liuling/p/2013-8-20-03.html
Copyright © 2011-2022 走看看