Venkatesh Marepalli
Venkatesh Marepalli

Reputation: 606

When a Thread is destroyed are the variables destroyed?

I wanted to process elements of Queue by 2 threads and prepare OutputQueue in same order as input. I still have to make some Synchronized blocks but I am stuck with the Following questions.

  1. Empty OutputQueue is returned
  2. Am I doing this the right way.

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

Upvotes: 2

Views: 1142

Answers (1)

Stephen C
Stephen C

Reputation: 719261

When a Thread is destroyed are the variables destroyed?

When the run() method call terminates, the thread stacks are discarded, and the thread's reference to its Runnable is nulled. By that time all of the run() method's local variables will be out of scope.

When the Runnable is becomes unreachable it is garbage collected. The GC is what will ultimately "destroy" the instance variables of the Runnable.


Am I doing this the right way.

I would use an ExecutorService, and deal with the issue of ordering the outputs by creating a list of Future objects returned by the submit(...) method.

In your code, you seem to have three distinct instance of HeavyWorkRunnable and you seem to be retrieving the output queue from the instance that you didn't pass to a thread. That doesn't look correct to me. There are also problems with (lack of) synchronization on the shared input queue. That could lead to race conditions and memory visibility problems.

Empty OutputQueue is returned

Yes. That is a consequence of the "three instances" problem above.

Upvotes: 4

Related Questions