Java 使用ReentrantLock时出现死锁
im使用ReentrantLock实现生产者-消费者问题Java 使用ReentrantLock时出现死锁,java,multithreading,Java,Multithreading,im使用ReentrantLock实现生产者-消费者问题 public class Processor { Lock lock = new ReentrantLock(true); Condition condn = lock.newCondition(); public void produce() throws InterruptedException{ lock.lock(); System.out.println("inside
public class Processor {
Lock lock = new ReentrantLock(true);
Condition condn = lock.newCondition();
public void produce() throws InterruptedException{
lock.lock();
System.out.println("inside producer method");
condn.await();
System.out.println("thread again wakeup");
lock.unlock();
}
public void consume() throws InterruptedException{
lock.lock();
Thread.sleep(1000);
condn.signal();
System.out.println("will i ever be ok ");
lock.unlock();
}
}
有两种方法通过ReentrantLock同步,但有时进程会因
o/p
我会好起来吗
内部生产者法
运行堆转储时
参考处理程序“#2守护程序优先级=10 os_优先级=31 cpu=0.26ms已用时间=540.35s tid=0x00007fd5f186f800 nid=0x4603等待条件[0x0000700002357000]
java.lang.Thread.State: RUNNABLE
at java.lang.ref.Reference.waitForReferencePendingList(java.base@11.0.1/Native Method)
at java.lang.ref.Reference.processPendingReferences(java.base@11.0.1/Reference.java:241)
at java.lang.ref.Reference$ReferenceHandler.run(java.base@11.0.1/Reference.java:213)
"Finalizer" #3 daemon prio=8 os_prio=31 cpu=0.67ms elapsed=540.35s tid=0x00007fd5f1883000 nid=0x4303 in Object.wait() [0x000070000245a000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(java.base@11.0.1/Native Method)
- waiting on <0x0000000787f08f80> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(java.base@11.0.1/ReferenceQueue.java:155)
- waiting to re-lock in wait() <0x0000000787f08f80> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(java.base@11.0.1/ReferenceQueue.java:176)
at java.lang.ref.Finalizer$FinalizerThread.run(java.base@11.0.1/Finalizer.java:170)
"Signal Dispatcher" #4 daemon prio=9 os_prio=31 cpu=0.34ms elapsed=540.27s tid=0x00007fd5f1884000 nid=0x3903 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Thread-0" #12 prio=5 os_prio=31 cpu=1.72ms elapsed=540.07s tid=0x00007fd5f00c7000 nid=0xa303 waiting on condition [0x0000700002d75000]
java.lang.Thread.State: WAITING (parking)
at jdk.internal.misc.Unsafe.park(java.base@11.0.1/Native Method)
- parking to wait for <0x0000000787ed4030> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(java.base@11.0.1/LockSupport.java:194)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@11.0.1/AbstractQueuedSynchronizer.java:2081)
at Processor.produce(Processor.java:11)
at RunnableExample$1.run(RunnableExample.java:13)
at java.lang.Thread.run(java.base@11.0.1/Thread.java:834)
如果消费者先调用
消费
,然后生产者调用生产
,那么生产者将错过信号
,陷入困境。你可以使用相位器
。关键是,使用相位器
生产者会问“我错过了一些消费吗?”?“如果没有,它正在等待,如果是,它将立即继续。以下是一个例子:
public class Processor {
private final Phaser phaser = new Phaser(1);
private volatile int lastPhaseId = 0;
public void produce() throws InterruptedException{
System.out.println("inside producer method");
lastPhaseId = phaser.awaitAdvance(lastPhaseId);
System.out.println("thread again wakeup");
}
public void consume() throws InterruptedException{
Thread.sleep(1000);
phaser.arrive();
System.out.println("will i ever be ok ");
}
}
这适用于单个消费者的情况。如果假定多个消费者处于
阶段。到达()
需要互斥访问和/或相应地更改注册方(取决于您需要什么语义)如何避免itI建议不要重新发明轮子,请使用JDK提供的阻塞队列
。。。或者简单地使用synchronized
?可能重复@oleg.cherednik该问题的答案没有一个真正提供答案,只是转储代码。我认为对这样一个问题闭嘴是没有帮助的。
public class Processor {
private final Phaser phaser = new Phaser(1);
private volatile int lastPhaseId = 0;
public void produce() throws InterruptedException{
System.out.println("inside producer method");
lastPhaseId = phaser.awaitAdvance(lastPhaseId);
System.out.println("thread again wakeup");
}
public void consume() throws InterruptedException{
Thread.sleep(1000);
phaser.arrive();
System.out.println("will i ever be ok ");
}
}