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