我需要构建一个具有优先级的“不公平信号量”。例如:当优先级为1的线程想要获取信号量时,它只需等待具有相同优先级的另一个线程完成,然后就可以获取()。但是,当优先级为2的线程想要获取信号量时,它必须等待优先级为1的所有线程完成后才能使用信号量,然后尝试获取()。我总共有4个不同的优先事项。这是我尝试过的,但没有成功。
有人有什么解决办法吗?
public class UnfairSemaphore
{
private Semaphore mPrior1;
private Semaphore mPrior2;
private Semaphore mPrior3;
private Semaphore mPrior4;
public UnfairSemaphore()
{
mPrior1 = new Semaphore(1);
mPrior2 = new Semaphore(1);
mPrior3 = new Semaphore(1);
mPrior4 = new Semaphore(1);
}
public void acquire(int priority) throws InterruptedException
{
if(priority == 1)
{
mPrior1.acquire();
}
else if(priority == 2)
{
while(mPrior1.hasQueuedThreads() && mPrior1.availablePermits() <=0)
{
//wait();
}
mPrior2.acquire();
mPrior1.acquire();
}
else if(priority == 3)
{
while(mPrior1.hasQueuedThreads() && mPrior1.availablePermits() <=0 && mPrior2.hasQueuedThreads() && mPrior2.availablePermits() <=0)
{
//wait();
}
mPrior3.acquire();
mPrior2.acquire();
mPrior1.acquire();
}
else
{
while(mPrior1.hasQueuedThreads() && mPrior1.availablePermits() <=0 && mPrior2.hasQueuedThreads() && mPrior2.availablePermits() <=0 && mPrior3.hasQueuedThreads() && mPrior3.availablePermits() <=0)
{
//wait();
}
mPrior4.acquire();
mPrior3.acquire();
mPrior2.acquire();
mPrior1.acquire();
}
}
public void release(int priority)
{
if(priority == 1)
{
mPrior1.release();
}
else if(priority == 2)
{
mPrior1.release();
mPrior2.release();
}
else if(priority == 3)
{
mPrior1.release();
mPrior2.release();
mPrior3.release();
}
else
{
mPrior1.release();
mPrior2.release();
mPrior3.release();
mPrior4.release();
}
//notifyAll();
}
}
为什么要自己管理线程?
您应该使用Thread类中的synchronized关键字和setPriority方法。
查看以下链接:
https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#setPriority(int)
https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
基本要求是,我们有一群等待的线程,每个线程都有一个优先级。在发布时,我们选择一个优先级最高的等待线程,并将其唤醒。
这可以通过锁定支持中的线程park()和unpark()来完成。它是一个低级并发工具,但我们不使用它来实现精英化;我们之所以使用它,是因为它最自然地模拟了我们的解决方案。
首先,我们需要一个存储等待线程及其优先级的数据结构。你可以通过多种方式做到这一点。
void storeWaitingThread(Integer priority, Thread thread) { ... }
// select and remove a waiting thread with highest priority; return null if none.
Thread selectWaitingThread(){ ... }
现在,release()
将只选择一个等待的线程,然后对其进行解压
final Object lock = new Object();
volatile Thread owningThread;
public void release()
{
synchronized (lock)
{
Thread nextOwner = selectWaitingThread();
owningThread = nextOwner;
}
LockSupport.unpark(owningThread);
}
<代码>获取(优先级)将当前线程存储为等待线程;驻车,直到选中为止
public void acquire(int priority)
{
Thread thisThread = Thread.currentThread();
synchronized (lock)
{
if(owningThread==null)
{
owningThread=thisThread;
return;
}
storeWaitingThread(priority, thisThread);
}
while(owningThread!=thisThread)
{
LockSupport.park();
// interrupt ignored. // todo handle interrupt
}
}
请参阅完整代码https://gist.github.com/zhong-j-yu/3ea91194f55d91059789
请注意,我们的获取
将忽略中断。如果它应该保释中断,请在park()
唤醒后添加一些逻辑。
问题内容: 以下是典型的读写器模式(很多读取而很少写入) 我想知道是否有可能优先考虑作家和读者?例如,如果其他线程不断持有读取锁,通常writer可能会等待很长一段时间(也许永远),因此有可能使writer具有更高的优先级,因此只要有writer出现,就可以认为它是高优先级(跳过行)之类的。 问题答案: 按照javadoc的,JDK实现并 不会 有任何读/写器的优先级。但是,如果你使用了“公平”的
根据优先表,一元后缀递增和递减运算符比关系运算符有更多的优先级,那么为什么在这样的表达式(x++>=10)中,关系运算符首先计算,然后变量递增呢?
我需要建立一个队列,其中元素将在默认情况下按时间顺序添加和删除。但是,如果客户机为队列设置了优先级标志,我需要能够根据元素的优先级顺序提取元素。 我正在考虑创建一个优先级队列,它由一个映射支持,以优先级顺序跟踪队列索引,基于优先级标志,我可以从映射中提取项目,并从队列中弹出项目。 然而,对于这种方法,问题是,我是默认创建地图,还是只在设置了标志的情况下创建地图(考虑到创建动态地图的成本很高,我倾向
我知道PriorityQueues的迭代器没有返回正确的顺序,因此我查看顺序的能力受到限制--但是我可以看到元素离开队列的顺序,而且它显然没有按照我希望的路径运行。 建议?
我需要一个优先级队列,它首先获得具有最高优先级值的项目。我当前正在使用队列库中的PriorityQueue类。但是,这个函数只先返回值最小的项。我尝试了一些很难看的解决方案,比如(sys.maxint-priority)作为优先级,但我只是想知道是否存在更优雅的解决方案。
问题内容: 在来自http://leepoint.net/notes- java/data/expressions/precedence.html的 一个示例中 以下表达式 被评估为 然后我从http://www.roseindia.net/java/master-java/operator- precedence.shtml 看到了另一个示例 以下表达式 被评估为 我对如何确定在涉及*和/时将首