1

我正在研究一個簡單的信號量程序,其中我正在初始化一個信號量,計數爲4並啓動6個線程。 在run方法中,我正在獲取Semaphore鎖,並且在完成每個線程之後,我釋放鎖。信號量公平性參數不遵循先入先出

這裏是我的代碼:

import java.util.concurrent.Semaphore; 

public class SemaphoreTest { 

    static Semaphore semaphore = new Semaphore(4, true); 

    static class MyThread extends Thread{ 

     String name = ""; 

     public MyThread(String name){ 
      this.name = name; 

     } 

     public void run(){ 

      System.out.println(name+" going to acquire lock..."); 
      System.out.println("Available Permits = "+semaphore.availablePermits()); 

      try { 
       semaphore.acquire(); 
       System.out.println(name+" got permit."); 

       try{ 
        for(int i=1;i<=1;i++){ 
         System.out.println(name+" is performing operation "+i+". Available Semaphore permits are : "+semaphore.availablePermits()); 
         Thread.sleep(1000); 
        } 

       }finally{ 
        System.out.println(name+" Releasing lock..."); 
        semaphore.release(); 
        System.out.println("Available permits after releasing "+"name"+" = "+semaphore.availablePermits()); 
       } 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 


     } 
    } 

    public static void main(String[] args){ 
     Thread t1 = new MyThread("A"); 
     t1.start(); 

     Thread t2 = new MyThread("B"); 
     t2.start(); 

     Thread t3 = new MyThread("C"); 
     t3.start(); 

     Thread t4 = new MyThread("D"); 
     t4.start(); 

     Thread t5 = new MyThread("E"); 
     t5.start(); 

     Thread t6 = new MyThread("F"); 
     t6.start(); 
    } 

} 

這裏是結果:

A going to acquire lock... 
Available Permits = 4 
C going to acquire lock... 
A got permit. 
A is performing operation 1. Available Semaphore permits are : 3 
B going to acquire lock... 
Available Permits = 3 
B got permit. 
F going to acquire lock... 
E going to acquire lock... 
Available Permits = 2 
Available Permits = 3 
D going to acquire lock... 
Available Permits = 0 
C got permit. 
C is performing operation 1. Available Semaphore permits are : 0 
E got permit. 
E is performing operation 1. Available Semaphore permits are : 0 
Available Permits = 2 
B is performing operation 1. Available Semaphore permits are : 2 
A Releasing lock... 
E Releasing lock... 
Available permits after releasing name = 2 
D got permit. 
D is performing operation 1. Available Semaphore permits are : 1 
B Releasing lock... 
C Releasing lock... 
Available permits after releasing name = 1 
F got permit. 
F is performing operation 1. Available Semaphore permits are : 2 
Available permits after releasing name = 2 
Available permits after releasing name = 2 
D Releasing lock... 
F Releasing lock... 
Available permits after releasing name = 3 
Available permits after releasing name = 4 

現在作爲Java文檔:

java.util.concurrent.Semaphore中。信號量(int許可,布爾公平)

Cr用給定的許可證數量和給定的公平設置來消除信號量。

參數:
permits可用的許可證的初始數量。此值可能爲負值,在這種情況下,必須在授予任何獲取之前進行發佈。
fair如果此信號量將保證第一下爭許可證先出准許,否則爲假

構造函數信號量(INT許可證,布爾公平),保證先入先出。但就這個程序的輸出而言,情況並不相同。 鎖被獲得性如下:

A - >乙 - 「ç - >電子

而鎖被釋放如下:

A - >電子 - > B - > C

請按照預期建議嗎?或者有什麼我失蹤?

回答

2

許可證的發放順序僅僅是在方法中花費的時間的結果,並且與公平無關。

這裏的FIFO表示如果兩個線程調用semaphore.acquire()並且沒有許可證可用,那麼首先調用它的線程將是第一個在有可用時接收許可證的線程。

在您的示例中,A,B,C,E獲得許可,因爲他們首先撥打acquire - 而D和F必須等待許可證可用。然後,D似乎在F之前呼叫acquire,因此獲得第一個可用許可。

0

這裏有一個關於線程時間的誤解:你認爲一旦線程輸出消息它將獲得鎖,但實際上沒有理由爲什麼線程不應該被擱置在中間。

C: System.out.println(...); 
C: thread gets put on hold 
A: System.out.println(...); 
A: aquires lock 
B: System.out.println(...); 
B: aquires lock 
C: resumes 
C: aquires lock