在为工作线程使用简单的互斥锁和条件变量时,我的程序会出现一些罕见且零星的线程饥饿错误,我想阻止它。
以下是我正在做的一个简单示例。有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;
}
}
}
答案 0 :(得分:0)
生产者/消费者模式总是会饿死,过载或者毫无意义。这不是性能模式,而是用于抽象。
如果您使用concurrent BlockingQueue可以删除所有synchronized
,则可以更轻松地制作代码。