2017-03-05 2 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이라는 세 개의 고유 한 인스턴스가있는 것 같고 이 스레드로 전달되지 않은 인스턴스에서 출력 대기열을 검색하는 것 같습니다. 그건 나에게 맞지 않아. 또한 공유 입력 대기열에서 (부족한) 동기화 문제가 있습니다. 경쟁 조건 및 메모리 가시성 문제가 발생할 수 있습니다.

빈 OutputQueue는

을 반환됩니다. 그것은 위의 "세 가지 경우"문제의 결과입니다.

+0

그래서'hr.getOutputQueue()'를 호출하면 빈 목록이 반환됩니다. 't1.join()'이후에 이것을 호출하고 있기 때문에 Thread 클래스의 모든 변수가 이미 파괴되었다고 생각합니다. 'outputQueue()'를 어떻게 얻을 수 있습니까? 내 질문에 대한 귀하의 의견을 감사드립니다. –

+0

아니요. 잘못된 목록을보고 있으므로 빈 목록이 반환됩니다. 3 개의 별개의'HeavyWorkRunnable' 인스턴스에 대한 제 코멘트를보십시오. –

관련 문제