我目前正在回顾并发性,并希望再次检查我的理解。
假设我有一个简单的队列类,我想使用多个线程从队列中取出作业并运行。
class JobQueue {
static Queue<Job> jobq;
ExecutorService exec;
public void addJob(Job j)
synchronized(jobq) {
jobq.add(j)
}
public void runJob() {
synchronized(jobq) {
while (!jobq.isEmpty()) {
exec.submit(() -> jobq.poll().run());
}
}
}
请原谅我的语法,我很快把这些放在一起。无论如何,我有一个两部分的问题。
1.为了避免addJob
方法的饥饿,锁定!jobq.isEmpty()
然后解锁,然后单独锁定exec.submit...
,这样在检查jobq为空和轮询一个作业关闭之间,addJob
有机会获得锁,这是不是更好?
1.如果是上面的情况(最好在while
检查之后解锁),您将如何对这个同步对象进行解锁?因为exec.submit
嵌套在while
循环中,而while
循环又嵌套在synchronized(jobq)
循环中。
1条答案
按热度按时间rsl1atfo1#
1.为了避免
addJob
方法的饥饿,锁定!jobq.isEmpty()
然后解锁,然后单独锁定exec.submit...
,这样在检查jobq为空和轮询一个作业关闭之间,addJob
有机会获得锁,这是不是更好?在这种情况下,锁定整个
while{...}
循环是可以的,因为exec.submit...
没有做太多事情:当任务在另一个线程中执行时,它实际上只创建并返回Future
。另外,如果
!jobq.isEmpty()
和exec.submit...
分别被锁定,则会出现另一个问题:如果在这些锁之间另一个线程执行runJob()
并且jobq
变为空,该怎么办?