Java中的“无饥饿”实现

时间:2017-08-30 18:25:43

标签: java multithreading concurrency mutex condition-variable

在为工作线程使用简单的互斥锁和条件变量时,我的程序会出现一些罕见且零星的线程饥饿错误,我想阻止它。

以下是我正在做的一个简单示例。有4个工作线程调用“Producer”和一个调用prod.getTasks()的主线程。

此代码“无死锁”,但由于错误,显然不是“无饥饿”。

当我检测到线程饥饿或时钟跳跃(管家增量=1m18s317ms137μs765ns)时出错:

A)因为Producer线程处于等待状态的时间太长了? (我不这么认为,因为我相信一个线程可以在它准备好使用之前等待任意时间。当然超过1分钟。)

B)因为其中一个等待的工作线程被传递了太多次?

基本上任何有助于使这种饥饿免费的好建议都会受到赞赏。

class Producer implements Runnable
{
    private static ArrayList<Task> arrTasks = new ArrayList<Task>();

    void getTasks()
    {
        Task t = getTask(); // get Tasks from a producer specific recordset.    
        synchronized (arrTasks)
        {
            arrTasks.add(t);
            arrTasks.notify();
        }
    }

    void run()
    {
        while (true) 
        {
            Task t = null;

            synchronized (arrTasks)
            {
                if (arrTasks.size() == 0)
                    arrTasks.wait();

                if (arrTasks.size() > 0)
                    t = arrTasks.remove(0);
            }

            if (t != null)
                processTask(t);

            if (mExit) 
                break;
        }
    }
}

1 个答案:

答案 0 :(得分:0)

生产者/消费者模式总是会饿死,过载或者毫无意义。这不是性能模式,而是用于抽象。

如果您使用concurrent BlockingQueue可以删除所有synchronized,则可以更轻松地制作代码。