为什么Java';s信号量公平性是构造函数的参数,而不是acquire()/tryAcquire()调用?

为什么Java';s信号量公平性是构造函数的参数,而不是acquire()/tryAcquire()调用?,java,semaphore,Java,Semaphore,我完全看不出为什么这不是一个每买入期权。信号量可能会在具有不同公平性要求的不同代码路径(主检查进度/工人从队列抓取工作/…)中关闭。也许在一种情况下,我们希望公平地检查进度,而在另一种情况下,如果运行的工作人员只有足够的工作,我们希望同样的少数工作人员工作,以优化一级缓存命中率等。)tryAcquire是不公平的,即使您在构造函数中将公平设置为true 即使将此信号量设置为使用公平排序策略,也会 调用tryAcquire()将立即获得许可证(如果有) 可用,无论当前是否有其他线程正在等待。这 “

我完全看不出为什么这不是一个每买入期权。信号量可能会在具有不同公平性要求的不同代码路径(主检查进度/工人从队列抓取工作/…)中关闭。也许在一种情况下,我们希望公平地检查进度,而在另一种情况下,如果运行的工作人员只有足够的工作,我们希望同样的少数工作人员工作,以优化一级缓存命中率等。)

tryAcquire
是不公平的,即使您在构造函数中将
公平
设置为true

即使将此信号量设置为使用公平排序策略,也会 调用
tryAcquire()
将立即获得许可证(如果有) 可用,无论当前是否有其他线程正在等待。这 “驳船”行为在某些情况下是有用的,即使 这破坏了公平。如果你想尊重公平设置,那么 使用
tryAcquire(长,时间单位)tryAcquire(0,时间单位。秒)
这几乎是等效的(它还检测中断)

--



我认为这种行为足以实现您概述的场景(检查进度与抓取工作)。

谢谢。但我认为这是两件不同的事情。在sane实现中,tryAcquire()与acquire()的唯一不同之处在于它返回failed而不是休眠。公平与否取决于如果有侍者(一场比赛),它是否会在不睡觉的情况下得到锁。因此,公平性(如果有的话)首先起作用,如果它没有在userland中获得锁,try会使它不休眠,而是失败。换句话说,在一个理智的实现中,我应该能够:while(sem.tryAcquire(fair)){sem.grant();}并且永远不会阻止自己,也不会让别人挨饿。干杯,我不明白这个问题。线程1要求公平并得到了它(意味着去操作系统睡觉,像其他服务员一样争夺锁)。线程2没有得到锁,因为他愿意在不睡觉的情况下抓住锁,即使有侍者,如果他不停地放手,紧紧抓住,他们也永远不会赢得比赛。公平的含义是排队,如果有服务员,没有别的。不要把它与韦伯斯特的定义混淆。这与上下文无关。我说语义是不恰当的。你说阅读文档。如果我们想让每个线程都对齐,没有理由强迫每个线程都对齐。因此,这是一种任意的限制。如果程序员想按你的方式去做,他可以公平地打电话。你还必须证明他必须穿制服的一个原因。至于FIFO,你无法控制它。操作系统将决定谁被唤醒。您只需选择进入操作系统睡眠,以及它应该醒来多少次。你可以期待先进先出。但除非你能告诉我在Linux(man 7 futex或man 2 futex)中的位置,否则它说FIFO,Java也不能保证这一点。它与Linux上的futex完全相关,因为这是获得操作系统提供的抢先多任务处理的唯一途径。如果您不相信我的话,请在一个紧循环中创建锁争用,并在争用的情况下查看Java对OS的系统调用。至于我创建“我自己的”,语义应该只在有意义时才创建限制。你能说出这个限制存在的唯一原因吗?为什么每次调用不能指定此参数?这是唯一有争议的问题,正如我在发布之前所预期的那样,没有人能够给出一个好的理由。顺便说一句,如果你真的想尝试strace'ing它,请记住,要从子线程获取系统调用,你需要strace-f