Say I have class A and class B. class A has just a main method with the following code:
public class A{
public static void main(String[] args){
String xput = "";
ExecutorService pool = Executors.newFixedThreadPool(4);
for(int i = 1; i < number; i++){
pool.submit(new B(list.get(i-1)));
xput = B.returnValue;
System.out.println(xput);//testing purposes
}
}
}
class B extends Thread, and looks like this:
public class B extends Thread{
static String returnValue = "";
public B(String x){
super(x);
}
public void run(){
double x = 20;
returnValue += "Grand total: " +
NumberFormat.getCurrencyInstance().format(x) + "\n";
}
}
Yet System.out.println(xput) does not print anything except an empty line. Anyone know why? My classes have a lot more code than this obviously, but since I’m not getting any output, I’m starting with a small case.
This code suffers from a number of race conditions since they are all updating the same
static String returnValue. Also the threads may actually not have run yet when theSystem.out.println(xput)is called. You would need to use thefuture.get()method to wait for each of the threads to finish and you can’t do that in the same loop where you submit them to the thread-pool.Since 4 threads will be running at once, and they all are updating the same
staticfield, you need to provide some synchronization around that variable. What I would recommend instead is to use theFuturefeatures of theExecutorServiceinstead of modifying the static field. Something like the following should work:The
Futurefeatures of theExecutorServiceallow you to get results from each of the jobs that were processed by the thread-pool. You cansubmit()Callableclasses which can return a resultString(or other object) from thecall()method.Also, your
Bshould implementCallablenot extendThread. Although it would work, it is only becauseThreadimplementsRunnableas well. The thread-pool has its own internal threads and you only submitRunnableorCallableobjects to it.Lastly, instead of using a
for (int iloop when processing lists (or any Java collection), you should get into the habit of using:If you have to use the
for (int ithen at least go from 0 to thesize()of the list:That way if you change the size of list you don’t have to remember to change your loop as well.