Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用ReentrantLock时出现死锁_Java_Multithreading - Fatal编程技术网

Java 使用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

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 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 ");
    }
}