簡體   English   中英

在多線程程序中未獲得預期的結果

[英]Not Getting expected result in multi-threaded program

我沒有在下面的程序中得到預期的結果,我期望生產者和使用者方法都應按一定順序執行,但是由於某些原因,只有生產者方法正在執行。

我在這里有兩個問題:

  1. 我無法理解這種行為。
  2. 在main方法的最后一行將兩個線程連接在一起正常工作,我無法理解兩者之間的區別。

     public class ProducerConsumer { List<Integer> data = new ArrayList<>(); synchronized void produce() throws InterruptedException { for (int i = 0; i < 10; i++) { System.out.println("Producing"); data.add(i); } wait(); } synchronized void consume() throws InterruptedException { System.out.println("Consuming"); data.clear(); notify(); } public static void main(String[] args) throws InterruptedException { ProducerConsumer pc = new ProducerConsumer(); Runnable r2 = ()-> { try { pc.produce(); } catch (InterruptedException e) { e.printStackTrace(); } }; Thread thread1 = new Thread(r2); thread1.start(); thread1.join(); Runnable r1 = () -> { try { pc.consume(); } catch (InterruptedException e) { e.printStackTrace(); } }; Thread thread = new Thread(r1); thread.start(); thread.join(); } 

    輸出:生產產品生產產品生產產品生產產品生產產品生產產品生產產品生產產品生產產品生產。

produce()方法以wait()結尾。 因此它將阻塞,直到有線程通知它為止。

唯一執行此操作的線程是使用者線程。 但是,只有在生產者線程結束之后,才通過main方法啟動消費者線程。 它直到被通知才結束。 所以你陷入僵局。

如果僅在兩個線程啟動之后才join() ,則使用者線程可以啟動而不必等待生產者線程完成。 這仍然不能使程序正確,因為

  • 您不能保證生產者線程將首先執行
  • 然后在末尾調用wait()是沒有用的
  • 從循環中調用wait()來檢查條件是否不正確
  • 如果要按順序執行方法,則使用線程是沒有用的。 您可以從主線程執行所有操作。

1) notify()調用根本不執行任何操作 除非其他線程已經在等待通知。

您有責任保證在線程中的任何一個調用wait()任何時間,其他線程將在wait()開始的某個時間notify()同一對象。

Oracle的“ 保護塊指南”在解釋o.wait()o.notify()工作原理方面做得很好,並且解釋了如何建立保證。

2)實際上沒有理由這樣做:

Thread t = new Thread(r);
t.start();
t.join();

您的程序將使用更少的CPU,並且將使用更少的內存,並且如果您只調用r.run() ,它將完成完全相同的操作。 線程的整個要點是允許不同的事情並發發生,並且如果一個線程在創建新線程后立即joins新線程,則不會並發。 除非您對它執行以下操作,否則將浪費新的Thread對象:

Thread t = new Thread(r);
t.start();
doSomethingElseWhileThread_t_isRunning();
t.join();

3) wait()notify()是線程之間進行通信的一種非常底層的方法。 如果您使用在wait()notify()之上構建的高層同步對象 ,而不是直接調用它們,則代碼將更易於閱讀和理解。

一個java.util.concurrent.ArrayBlockingQueue實例將特別適合於“生產者/消費者”應用程序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM