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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM