|
|
1
1
我想指出你犯了两个错误:
每个对象都可以用于一个内部锁,因此不需要查找特定的
一旦你进入一个同步块,没有人可以进入那里,直到你离开它。显然,你永远不会退出,因为
我建议你把
|
|
|
2
2
@反义词是对的。您没有正确使用ReentrantLock,而是可以用一个对象替换它。如果您想改用ReentrantLock(它更为流行),那么我建议如下:
我删除了notify调用,但是如果您真的需要一次引入一个线程,只需使用lock.notify() |
|
|
3
1
如你所愿
在制作过程中,您只需:
而在消费者中
瞧,消费者会接受任何值,并等待值队列为空。 至于你的代码:
这里的问题是你的执行
从不离开同步块
是的。所以你打电话来
你可以想象房间里有几个PPL,只有一个拿着棍子的能说话。所以第一个得到了
|
|
|
4
1
你获得并释放
正如antoniosss所指出的,这是一个死锁,其中一个线程正在等待另一个线程永远不会放弃的锁(而两个线程正试图协调该锁)。以下是一个解决方案:
我们已经去掉了lock对象并在列表中进行了同步。producer在while循环中进行同步,其效果是一旦列表中至少有5个项,producer将等待,放弃列表中的监视器。
使用者还可以在循环内进行同步,这一点非常关键,因为在您的代码中,一旦获取了锁,它就永远不会放弃锁上的监视器。事实上,如果你先开始消费(或者很不走运),根本就不会生产任何东西。当离开一个同步块或方法时,或者当一个线程持有监视器时,监视器被释放
使用者读取最后一个项目(如果有),然后立即通知生产者并释放锁。两个注释: 首先,还不清楚你对商品的要求是什么。你希望生产商生产5个,消费者消费5个,等等,或者你希望5个只是一个限制,太大的积压无法形成(这是好的,它被称为背压),但消费者消费项目急切时,他们有空吗?这种实现实现实现了后者。
其次,消费者一旦发布了清单上的监视器,就会试图获取它。这是一种
忙着等待
,然后消费者和生产者竞相获取锁,可能是消费者经常赢得这场比赛,一旦列表为空,这将变得毫无意义。打个电话给
antoniosss提出了另一个建议,即使用linkedblockingqueue,但目前的代码总是使用最后一个项,而使用queue将改变这种行为。相反,我们可以使用deque(一个双端队列),将项目放在末尾,并从末尾获取它们。下面是它的样子:
因为
没有什么可以阻止生产者尽可能快地生产出消费者能够消费的元素,这意味着第一个元素可能需要等待任意长的时间才能被消费。我不清楚这是否是你代码的意图。你可以通过介绍
最后一点说明
|
|
|
JLosc · Powershell脚本因文件锁定而失败 1 年前 |
|
|
Sriram Umapthy · PostgreSql行级锁 2 年前 |
|
|
a a · 为什么在这个可重入锁示例中需要引用计数? 3 年前 |
|
|
JohnLBevan · 为什么原子语句上需要锁提示? 8 年前 |