当前位置: 首页 > 知识库问答 >
问题:

在JAVA中具有优先级的互斥

曹均
2023-03-14

我需要构建一个具有优先级的“不公平信号量”。例如:当优先级为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();
    }
}

共有2个答案

阎涵容
2023-03-14

为什么要自己管理线程?

您应该使用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

戚修雅
2023-03-14

基本要求是,我们有一群等待的线程,每个线程都有一个优先级。在发布时,我们选择一个优先级最高的等待线程,并将其唤醒。

这可以通过锁定支持中的线程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 看到了另一个示例 以下表达式 被评估为 我对如何确定在涉及*和/时将首