2017-02-15 52 views
1

代码进入死锁。即使它一出现wait()即将生产者部分,它就陷入僵局。从我的理解,如果wait()被击中,它应该去消费者线程,而不是进入死锁。我的生产者消费者代码进入死锁

package com.java.thread.self.practice; 

public class Producer_Consumer { 

     private volatile boolean prodFlag = true; 
     private volatile boolean consFlag = false; 

     public static void main(String[] args){ 

      Producer_Consumer producer_Consumer = new Producer_Consumer(); 
      producer_Consumer.startThreads(); 

     } 

     private void startThreads() { 

      Thread producer = new Thread(new Runnable(){ 

       @Override 
       public void run() { 
        while(true){ 
         try { 
          System.out.println("Before Producer invocation :::::: "); 
          producer(); 
          Thread.sleep(100); 
         } catch (InterruptedException e) { 
          // TODO Auto-generated catch block 
          e.printStackTrace(); 
         } 
        } 

       } 

      }); 



      Thread consumer = new Thread(new Runnable(){ 

       @Override 
       public void run() { 
        while(true){ 
         try { 
          System.out.println("Before Consumer invocation :::::: "); 
          consumer(); 
          Thread.sleep(100); 
         } catch (InterruptedException e) { 
          // TODO Auto-generated catch block 
          e.printStackTrace(); 
         } 
        } 
       } 

      }); 


      producer.start(); 
      consumer.start(); 
     } 

     void producer() throws InterruptedException { 

      System.out.println("Inside the producer method ::::: "+this.getClass()); 

      synchronized(this){ 

       if(prodFlag){ 

        System.out.println("PRODUCE !!!"); 
        consFlag = true; 
        System.out.println("Before calling wait in producer :::::: "); 
        notify(); 
        wait(); 
        System.out.println("After calling wait in producer :::::: "); 

       }else{ 

        System.out.println("Before calling notify in producer :::::: "); 
        consFlag = true; 
        wait(); 
        System.out.println("After calling notify in producer :::::: "); 

       } 


      } 
     } 

     void consumer() throws InterruptedException { 

      System.out.println("Inside the consumer method ::::: "+this.getClass()); 

      synchronized(this){ 

       if(consFlag){ 

        System.out.println("CONSUME !!!"); 
        prodFlag = true; 
        System.out.println("Before calling wait in consumer :::::: "); 
        notify(); 
        wait(); 
        System.out.println("After calling wait in consumer :::::: "); 

       }else{ 

        System.out.println("Before calling notify in consumer :::::: "); 
        prodFlag = true; 

        wait(); 

        System.out.println("After calling wait in consumer :::::: "); 

       } 

      } 
     } 
} 
+0

我测试了你的代码,它没有死锁。他连续打印控制台中的“生产”“消费” – Flood2d

+0

尝试调试模式。 –

+1

如果生产者线程和消费者线程调用'notify()',然后他们都调用'wait()',会发生什么?你在想什么会唤醒他们其中一个呢? –

回答

2

当你做到这一点

synchronized(this) 

你锁定全班。它将被锁定,直到该代码块结束。既然你声明你的标志volatile应该不需要显式同步。

在这种情况下,您根本不需要发出wait()notify的信号。但是,如果你想拥有一些原子商业逻辑,你需要重新修改你的代码,不要把你的类作为关键块阻塞整个大块。

+0

“这里不应该是需要显式同步的。”除了这个事实[你必须让监视器调用wait和notify](https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#wait())。 –

+0

感谢您的输入。 即使我尝试使用易失性关键字进行删除,它仍会陷入僵局。我的问题是,如果它等待(),它应该去消费者线程,而不是去死锁。 –

+0

我的问题是为什么它不会消费块,一旦它碰到生产者块中的wait()。 –

1

程序不会进入死锁状态 - 无论是在运行时还是在调试时。我想你不熟悉调试多个线程,对吧?也许在你看来,当你不得不切换到消费线程并继续调试时,你的生产线程处于死锁状态?

相关问题