views:

126

answers:

1

This is my code. As you see in the run method, I assign values to tStart, tEnd, tAround and wTime. But when the Thread ends, they still have the default values of -1. I try printing out their values while the run() is running, and I have the correct values. But they are not 'writing' those values back to the variables when the thread ends.

public class PCB extends Thread{
 public int id, arrivalTime, cpuBurst, ioBurst;
 public int tStart, tEnd, tAround, wTime;
 public PCB(){
  id = -1;
  arrivalTime = -1;
  cpuBurst = -1;
  ioBurst = -1;

  tStart = -1;
  tEnd = -1;
  tAround = -1;
  wTime = -1;
 }

 public void run(){
  try{
 .........

   //calculation for FCFS 
   if (id == 1){ //special case for the first one
    tStart = arrivalTime;
   }
   else tStart = lastEndTime;

   tEnd = tStart + cpuBurst + ioBurst;
   tAround = tEnd - arrivalTime;
   wTime = tStart - arrivalTime;

                            PCBThreadStopFlag = true;   

  }
  catch(InterruptedException e){
   e.printStackTrace();
  }
 }
}

When the thread ends, this is how I print out the values:

     // now we print out the process table
 String format = "|P%1$-10s|%2$-10s|%3$-10s|%4$-10s|%5$-10s|%6$-10s|%7$-10s|%8$-10s|\n";
 System.out.format(format, "ID", "ArrTime", "CPUBurst", "I/OBurst", "TimeStart", "TimeEnd","TurnAround","WaitTime");
 ListIterator<PCB> iter = resultQueue.listIterator();
 while(iter.hasNext()){
  PCB temp = iter.next();
  System.out.format(format, temp.id, temp.arrivalTime, temp.cpuBurst, temp.ioBurst, temp.tStart, temp.tEnd, temp.tAround, temp.wTime );
 }

And here is how I waited for the thread to stop first:

while(!rq.values.isEmpty()){
   //System.out.println("Ready queue capacity now: " + rq.values.size());
   currentProcess = new PCB(rq.values.getFirst());
   currentProcess.start();

   while(PCBThreadStopFlag == false) {}
   //currentProcess.stop();
   PCBThreadStopFlag = false;

   //after everything is done, remove the first pcb
   // and add it to the result queue (just to print the report)
   resultQueue.addLast(rq.values.removeFirst());   
  }

I use the flag PCBThreadStopFlag in the run() up top (at the end when all the assignments are done) then in this function, I use while(PCBThreadStopFlag == false) {} to do the "busy-wait" task. may be this is the cause??

+3  A: 

This is just a guess, but I'll bet you're not joining on the threads before you print the results. In other words I suspect you're starting the threads and then immediately printing the result without waiting for the threads to complete.

EDIT: OK, try this...

Idea #1: Declare the PCBThreadStopFlag as volatile, and try again. Tell us if that works.

Idea #2: Get rid of the whole stop flag thing altogether, and replace the busy wait with

currentProcess.join();

and tell us if that works.

Willie Wheeler
actually I wait for it to stop, then I print the results.
SimpleCode
Can you show us the code that you're using to spawn the threads, and also how you're waiting for the threads to stop?
Willie Wheeler
@Willie Wheeler - Nice thought, I didn't think about not joining. :)
James Black
Yep, I still think that's what the issue is, but I'll wait to see the code... :-)
Willie Wheeler
I updated the code above, thanks!
SimpleCode
+1 - I expect your solution is correct, but he needs to exit when the flag tells him to, so the join will work.
James Black
Wait, I removed it for a minute. I was assuming that he is spawning a bunch of threads in parallel. That does not appear to be what he's doing. His outermost loop creates a single thread and then busy-waits til the thread is done. So joining on threads won't help.@SimpleCode, what's the rq.values thing?
Willie Wheeler
guys, actually I found it was because of my stupid mistake. Willie is right, they are not parallel. In the code above, I use currentProcess = new PCB(rq.values.getFirst()); and change the values in the run() in this new PCB (currentProcess) but when I updated it to the list, I updated resultQueue.addLast(rq.values.removeFirst());. It's supposed to be like this: rq.values.removeFirst(); resultQueue.addLast(currentProcess);Very basic mistake. It works now. Thank you so much for all your help. As a newbie in this all Java thread stuff, I really appreciate your help guys!!
SimpleCode
I need to take a look at the join() concept too. Thank you so much for your help. And have the rest of the Halloween night full of peace!!! Again. I THANK YOU sooo much for you support.
SimpleCode
OK, but still get rid of that busy-wait. Replace it with currentProcess.join(). It will still work and will avoid spinning the CPU too. Good luck!
Willie Wheeler
Also--is there any reason in particular you're spawning a new thread over this? After all if you are just starting a single thread and then waiting for it to be done, why start a new thread at all? Just do the work on the main thread...??
Willie Wheeler
OH!! Wonderful! It runs much faster! Thanks Willie
SimpleCode
I'm implementing on the simulation of the CPU controlling its processes. In this particular case which is FCFS (first come first served) The new thread starts only after the previous thread ends (which is the worst algorithm of processes controlling) but I'll have to simulate RR (round robin) which will need processes running concurrently.
SimpleCode
Ah, gotcha. Makes sense then. When you get to RR scheduling, you will find join() very useful. You will want to do something like this: (1) Create all your threads and put them in a list. (2) Iterate over all of your threads, calling start() on each. (3) Immediately afterward, iterate over all of them again, calling join(). That will block the main thread from progressing to the report until after all workers have completed. Also check out java.util.concurrent.CyclicBarrier.
Willie Wheeler