LinkedList多线程在Runnable中创建单独的实例

lgp*_*lgp 0 java multithreading linked-list

代码说明了我的问题:

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);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

和输出(在哪个线程删除什么元素有所不同):

5 Thread#: 0
5 Thread#: 1
one Thread#: 0
three Thread#: 0
four Thread#: 0
five Thread#: 0
two Thread#: 1
Run Code Online (Sandbox Code Playgroud)

我希望{"one", "two", "three", "four", "five"}每次线程都移除两次.但是,似乎removeNumbersRunnables共享相同的localnumbersLinkedList.为什么会这样?我的理解是我创建了两个独立的实例localnumbers,每个removeNumbersRunnable中有一个实例.

Pau*_*ora 5

你将对它的引用传递给LinkedList<String>两个构造函数调用,所以每个localnumbers都指向相同的List.这就是为什么两者都从同一个中删除List,因为你还没有真正复制它.

你会想要做的事情:

LinkedList<String> numbers = new LinkedList(Arrays.asList(numbersarray));
for (int index = 0; index < 2; index++) {
    LinkedList<String> numbersCopy = new LinkedList<String>(numbers);
    tpe.execute(new removeNumbers(numbersCopy, index));
}
Run Code Online (Sandbox Code Playgroud)

有更有效的方法来制作这些副本.请注意,即使使用相同的数组对Arrays.asList()进行两次调用也不足以真正创建副本,因为该方法返回List由数组支持的方法.您将需要List在上面的循环中创建as的副本,或者使用System.arraycopy()在开头复制数组:

String[] numbersarray = {"one", "two", "three", "four", "five"};
String[] numbersarray2 = new String[numbersarray.length];
System.arraycopy(numbersarray, 0, numbersarray2, 0, numbersarray.length);
Run Code Online (Sandbox Code Playgroud)