我正在尝试在 java 中创建一个池对象的类。该类开始创建所需的最小数量的对象,当请求开始启动时,每个线程都会检查是否有可用的对象,是否可以创建它,因为尚未达到最大数量,否则它必须等待买一个。
这个想法是线程需要同步才能获取/创建引擎,但它们可以并行处理(ProcessWithEngine
方法)。处理过程可能需要几分钟,显然它正在按照我的意愿工作。
问题是,有时当 .notify()
被调用并且线程从 .wait()
中释放时,队列有 0 个项目,这应该是不可能的,因为就在 .notify()
之前,添加了一个项目。
可能是什么问题?
代码是这样的:
Queue _queue = new Queue();
int _poolMax = 4;
int _poolMin = 1;
int _poolCurrent =0;
public void Process(Object[] parameters) throws Exception
{
Engine engine = null;
synchronized(_queue)
{
if(_queue.isEmpty() && _poolCurrent >= _poolMax)
{
_queue.wait();
// HERE : sometimes _queue.isEmpty() is true at this point.
engine = (SpreadsheetEngine)_queue.dequeue();
}
else if (_queue.isEmpty() && _poolCurrent < _poolMax)
{
engine = CreateEngine();
_poolCurrent++;
}
else
{
engine = (Engine)_queue.dequeue();
}
}
ProcessWithEngine(engine, parameters);
// work done
synchronized(_queue)
{
_queue.enqueue(engine);
_queue.notify();
}
}
我已经修复它这样做:
do
{
_queue.wait();
}
while(_queue.isEmpty());
但基本上这意味着线程正在失去其轮次,并且可能意味着稍后超时。
最佳答案
对 .wait()
的所有调用都必须包含在 while
循环中。调用 wait()
可以随机唤醒。
根据documentation :“与单参数版本一样,中断和虚假唤醒是可能的,并且此方法应始终在循环中使用:”
关于java - 使用 .wait 和 .notify 进行对象池,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5622428/