Code that illustrates my problem:
public class Linkedlisttest {
public static void main(String[] args) {
Linkedlisttest test = new Linkedlisttest();
test.go(args);
}
public void go(String[] args) {
int cpus = Runtime.getRuntime().availableProcessors();
ThreadPoolExecutor tpe = new ThreadPoolExecutor(cpus, cpus * 2, 1L,
TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
String numbersarray[] = {"one", "two", "three", "four", "five"};
LinkedList<String> numbers = new LinkedList(Arrays.asList(numbersarray));
for (int index = 0; index < 2; index++) {
tpe.execute(new removeNumbers(numbers, index));
}
}
class removeNumbers implements Runnable {
LinkedList<String> localnumbers;
int index;
public removeNumbers(LinkedList<String> localnumbers, int index) {
this.localnumbers = localnumbers;
this.index = index;
}
@Override
public void run() {
System.out.println(localnumbers.size() + " Thread#: " + index);
while (localnumbers.size() > 0) {
System.out.println(localnumbers.removeFirst() + " Thread#: " + index);
}
}
}
}
and the output (which varies somewhat in which thread removes what element):
5 Thread#: 0
5 Thread#: 1
one Thread#: 0
three Thread#: 0
four Thread#: 0
five Thread#: 0
two Thread#: 1
I’m expecting {"one", "two", "three", "four", "five"} to get removed twice, once by each thread. However, it seems like the removeNumbers Runnables are sharing the same localnumbers LinkedList. Why does this happen? My understanding is that I’ve created two separate instances of localnumbers, one in each removeNumbers Runnable.
You’re passing a reference to the same
LinkedList<String>into both constructor calls, so eachlocalnumbersis pointing to the sameList. That’s why both are removing from the sameList, because you haven’t actually copied it.You will want to do something along the lines of:
There are more efficient ways to make these copies. Note that even two calls to Arrays.asList() using the same array will not be enough to truly create copies, since that method returns a
Listbacked by the array. You will need to create copies of theListas in the loop above, or else use System.arraycopy() to copy the array at the beginning: