信号量公平参数不遵循先进先出

时间:2022-05-25 06:59:11

I am working on a simple Semaphore program in which i am initializing a Semaphore with a count of 4 and starting 6 threads. Inside the run method, i am acquiring the Semaphore lock and after completion of each thread, i am releasing the lock.

我正在开发一个简单的Semaphore程序,我正在初始化一个计数为4并开始6个线程的信号量。在run方法中,我正在获取Semaphore锁,并且在每个线程完成后,我将释放锁。

Here is my code:

这是我的代码:

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();
    }

}

And here is the result:

这是结果:

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

Now as of the java documentation:

现在作为java文档:

java.util.concurrent.Semaphore.Semaphore(int permits, boolean fair)

java.util.concurrent.Semaphore.Semaphore(int permits,boolean fair)

Creates a Semaphore with the given number of permits and the given fairness setting.

使用给定数量的许可和给定的公平设置创建信号量。

Parameters:
permits the initial number of permits available. This value may be negative, in which case releases must occur before any acquires will be granted.
fair true if this semaphore will guarantee first-in first-out granting of permits under contention, else false

参数:允许可用的初始许可数。此值可能为负值,在这种情况下,必须在授予任何获取之前发布。如果这个信号量能保证在争用中首先获得许可证,那么这是公平的,否则就是假的

The constructor Semaphore(int permits, boolean fair), guarantees first-in-first-out. But as of the output of this program, it is not the same. The locks are aquired as follows:

构造函数Semaphore(int permit,boolean fair)保证先进先出。但截至该计划的输出,它是不一样的。锁的获得如下:

A -> B -> C -> E

A - > B - > C - > E.

And the locks are released as follows:

锁的释放如下:

A -> E -> B -> C

A - > E - > B - > C.

Please suggest is it as expected? Or there is something i am missing?

请按照预期建议吗?或者有什么我想念的?

2 个解决方案

#1


2  

The order in which the permits are released is simply a consequence of the time spent in the run method and has nothing to do with fairness.

许可证被释放的顺序仅仅是在运行方法中花费的时间的结果,与公平性无关。

FIFO here means that if two threads call semaphore.acquire() and no permit is available, the thread that called it first will be the first to receive a permit when one becomes available.

这里的FIFO意味着如果两个线程调用semaphore.acquire()并且没有可用的许可,则首先调用它的线程将是第一个在可用时接收许可的线程。

In your example, A, B, C, E get permits because they call acquire first - and D and F have to wait for a permit to become available. Then it seems that D calls acquire before F and therefore gets the first available permit.

在您的示例中,A,B,C,E获得许可,因为他们首先调用获取 - 而D和F必须等待许可才可用。然后似乎D呼叫在F之前获得并因此获得第一个可用的许可。

#2


0  

There is a misunderstanding about thread timing here: you assume that as soon as the thread outputs the message it will acquire the lock, but in fact there is no reason why the thread should not be put on hold in between.

这里有一个关于线程时序的误解:你假设一旦线程输出消息它将获得锁定,但实际上没有理由不在这两个线程之间保持线程。

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

#1


2  

The order in which the permits are released is simply a consequence of the time spent in the run method and has nothing to do with fairness.

许可证被释放的顺序仅仅是在运行方法中花费的时间的结果,与公平性无关。

FIFO here means that if two threads call semaphore.acquire() and no permit is available, the thread that called it first will be the first to receive a permit when one becomes available.

这里的FIFO意味着如果两个线程调用semaphore.acquire()并且没有可用的许可,则首先调用它的线程将是第一个在可用时接收许可的线程。

In your example, A, B, C, E get permits because they call acquire first - and D and F have to wait for a permit to become available. Then it seems that D calls acquire before F and therefore gets the first available permit.

在您的示例中,A,B,C,E获得许可,因为他们首先调用获取 - 而D和F必须等待许可才可用。然后似乎D呼叫在F之前获得并因此获得第一个可用的许可。

#2


0  

There is a misunderstanding about thread timing here: you assume that as soon as the thread outputs the message it will acquire the lock, but in fact there is no reason why the thread should not be put on hold in between.

这里有一个关于线程时序的误解:你假设一旦线程输出消息它将获得锁定,但实际上没有理由不在这两个线程之间保持线程。

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