我正在为 OCP 考试做一些练习。目前,我尝试在使用多个线程时打印出CopyOnWriteArrayList的内容。根据文档, CopyOnWriteArrayList 的迭代器将
打印创建迭代器时存在的列表中的数字
因此,当在 CopyOnWriteArrayList 上启动一个线程写入并从 CopyOnWriteArrayList读取另一个线程时,我希望(有时)打印出一些项目。在编写线程完成后遍历 CopyOnWriteArrayList 时,我希望有一个新的迭代器打印出所有项目。
不幸的是,这在使用Runnable 接口的匿名实现时不起作用。但它在使用自定义线程类时有效,我在其中传递了对 CopyOnWriteArrayList 的引用。
现在,我不明白为什么会发生这种情况。我不确定是否final CopyOnWriteArrayList<Integer> intList = new CopyOnWriteArrayList<>();
会导致这种影响——如果是这样的话——我根本不知道为什么?
对此主题的任何意见将不胜感激!
使用 Runnable 的匿名实现 - 无法按预期工作
static void copyOnWriteCollections() {
System.out.println("copyOnWriteCollections".toUpperCase());
final CopyOnWriteArrayList<Integer> intList = new CopyOnWriteArrayList<>();
Thread tADD = new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 10000; i++) {
intList.add(i);
}
}
});
tADD.start();
/// will print the numbers in the list which are present
/// at the moment the iterator is created
Thread tREAD = new Thread(new Runnable() {
public void run() {
for (Integer i : intList) {
System.out.print(i);
System.out.print(" ");
}
}
});
tREAD.start();
try {
tADD.join();
tREAD.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// will print out all numbers - as iterator is created when all
// modifications
// to intList have finished
System.out.println();
new Thread(new Runnable() {
public void run() {
System.out.println("new");
System.out.println("\tsize of intList: " + intList.size());
Iterator<Integer> it = intList.iterator();
while (it.hasNext()) {
int i = it.next();
System.out.print(i);
System.out.print(" ");
}
System.out.println("end");
}
}).start();
}
使用自定义线程类 - 按预期工作
class CopyOnWriteThread extends Thread {
Iterator<Integer> it = null;
boolean read = false;
CopyOnWriteArrayList<Integer> intList = null;
public CopyOnWriteThread(CopyOnWriteArrayList<Integer> intList, boolean read) {
this.intList = intList;
this.read = read;
}
public void run() {
if (read) {
it = intList.iterator();
System.out.println("START read (" + Thread.currentThread().getName() + ")");
System.out.print("\t");
while (it.hasNext()) {
System.out.print(it.next());
System.out.print(" ");
}
System.out.println();
System.out.println("END read (" + Thread.currentThread().getName() + ")");
} else {
System.out.println("START write (" + Thread.currentThread().getName() + ")");
for (int i = 0; i < 10000; i++) {
intList.add(i);
}
System.out.println("END write (" + Thread.currentThread().getName() + ")");
}
}
}
static void copyOnWriteCollections_CustomThread() {
CopyOnWriteArrayList<Integer> intList = new CopyOnWriteArrayList<>();
CopyOnWriteThread tWRITE = new CopyOnWriteThread(intList, false);
CopyOnWriteThread tREAD = new CopyOnWriteThread(intList, true);
tWRITE.start();
tREAD.start();
try {
tWRITE.join();
tREAD.join();
} catch (InterruptedException e) {
}
CopyOnWriteThread tREAD2 = new CopyOnWriteThread(intList, true);
tREAD2.start();
}
目前我正在使用 JDK 1.7.0_25 和 Eclipse Mars Release 4.5.0 的 Win10 机器上工作