2017-03-05 15 views
2

キューの要素を2つのスレッドで処理し、入力と同じ順序でOutputQueueを準備したかったのです。私はまだいくつかの同期ブロックを作成する必要がありますが、私は次の質問に固執しています。スレッドが破棄されると、変数は破棄されますか?

  1. 空OutputQueueは
  2. 返された私は、この正しい方法を行っています。

ThreadMailClass.java

public class ThreadMainClass { 

    public static void main(String[] args) { 
     int[] inputQueue={2,3,4,5,6}; 
     processJobs(inputQueue); 
    } 

    public static void processJobs(int[] inputQueue){ 

     Queue<Integer> queue = new LinkedList<Integer>(); 
     for(int i:inputQueue){ 
      queue.add(i); 
     } 
     System.out.println("Input Queue Size:" + queue.size()); 

     HeavyWorkRunnable hr = new HeavyWorkRunnable(); 

     Thread t1 = new Thread(new HeavyWorkRunnable(queue),"t1"); 
     Thread t2 = new Thread(new HeavyWorkRunnable(queue),"t2"); 

     t1.start(); 
     t2.start(); 

     try { 
      t1.join(); 
     t2.join(); 

      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
//This method is returning empty Queue. 
     Queue<Integer> outputQueue = hr.getOutputQueue(); 
     System.out.println("Printing Output Queue.." + outputQueue.size()); 
     for(Integer i:outputQueue) 
      System.out.println(i); 
     System.out.println("Printing Done"); 


    } 

HeavyWorkRunnable.javaスレッドが破壊され

public class HeavyWorkRunnable implements Runnable { 

    private Queue<Integer> outputQueue = new LinkedList<Integer>(); 
    private Queue<Integer> inputQueue; 

    public HeavyWorkRunnable() { 

     } 
    public HeavyWorkRunnable(Queue<Integer> inputQueue) { 
     this.inputQueue = inputQueue; 
     } 

    @Override 
    public void run() { 
     System.out.println("Doing heavy processing - START "+Thread.currentThread().getName()); 
     try { 
      processInputQueue(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     System.out.println("Doing heavy processing - END "+Thread.currentThread().getName()); 
    } 

    private void processInputQueue() { 
     while(inputQueue.peek()!=null){ 
      System.out.println(Thread.currentThread().getName() + "-->input size -->"+ inputQueue.size()); 
      outputQueue.add(inputQueue.remove()); 
      System.out.println(Thread.currentThread().getName() + "-output size -->"+ outputQueue.size()); 
     } 
    } 

    public Queue<Integer> getOutputQueue() { 
     return this.outputQueue; 
    } 
} 
+0

複数のスレッドで 'LinkedList'をキューとして使用しています。これはスレッドセーフではありません。そのために同期を使用していません。あなたがするまでそれは正しく動作しません。 – EJP

答えて

4

は、変数が破壊されていますか?

run()メソッド呼び出しが終了

は、スレッドスタックは破棄され、その Runnableにスレッドの参照がゼロにされます。その時点までに、メソッドのローカル変数のすべてが範囲外になります。 run()

Runnableにアクセスできなくなると、ガベージコレクションされます。 GCは、Runnableのインスタンス変数を最終的に「破壊する」ものです。


私はこの正しい方法を行っています。

私はExecutorServiceを使用し、submit(...)メソッドによって返さFutureオブジェクトのリストを作成することにより、出力を注文する問題に対処するでしょう。

コードでは、HeavyWorkRunnableという3つの異なるインスタンスがあり、になっていないインスタンスから出力キューを取得しているようです。それは私には正しいとは思わない。また、共有入力キューの(不足している)同期に問題があります。競合状態やメモリの可視性の問題につながる可能性があります。

空OutputQueueは、はい

が返されます。これは、上記の「3つのインスタンス」問題の結果です。

+0

だから、 'hr.getOutputQueue()'を呼び出すと空のリストが返されます。私は 't1.join()'の後にこれを呼び出しているので、ThreadクラスとThreadクラスのすべての変数はすでに破棄されていると思います。 'outputQueue()'を取得するにはどうしたらいいですか?私の質問にあなたの入力を感謝します。 –

+0

いいえ。間違ったリストを見ているので、空のリストを返しています。 3つの異なる 'HeavyWorkRunnable'インスタンスに関する私のコメントを見てください。 –

関連する問題