首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >信号量公平参数不跟随先入先出

信号量公平参数不跟随先入先出
EN

Stack Overflow用户
提问于 2017-07-11 10:20:01
回答 2查看 875关注 0票数 3

我正在编写一个简单的信号量程序,在这个程序中,我使用计数为4的信号量初始化一个信号量,并启动6个线程。在run方法中,我获取信号量锁,在完成每个线程之后,我将释放锁。

这是我的代码:

代码语言:javascript
复制
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();
    }

}

其结果是:

代码语言:javascript
复制
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.Semaphore(整数许可,布尔公平) 使用给定数量的许可证和给定的公平设置创建一个信号量。 参数: permits许可的初始数量。此值可能为负值,在这种情况下,必须在授予任何获取之前进行释放。 fair true如果此信号量将保证先入先出授予争用的许可证,否则为假。

构造函数信号量(int允许,布尔公平),保证先进先出.但是对于这个程序的输出,它是不一样的。这些锁的要求如下:

-> B -> C -> E

锁按以下方式释放:

一种-> E -> B -> C

请建议它是否如预期的那样?还是我错过了什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-07-11 10:30:21

发放许可证的顺序只是run方法所花费时间的结果,与公平性无关。

FIFO在这里意味着,如果两个线程调用semaphore.acquire(),而没有可用的许可,那么首先调用它的线程将是第一个获得许可的线程。

在你的例子中,A,B,C,E得到许可,因为他们首先调用acquire,而D和F必须等待许可才能生效。然后,似乎D在F之前调用了acquire,因此获得了第一个可用许可。

票数 3
EN

Stack Overflow用户

发布于 2017-07-12 13:26:05

这里有一个关于线程定时的误解:您假设只要线程输出消息,它就会获得锁,但实际上没有理由不让线程在这两者之间暂停。

代码语言:javascript
复制
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
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45031767

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档