gpt4 book ai didi

java - CopyOnWriteArrayList 上线程中的迭代器不起作用

转载 作者:太空宇宙 更新时间:2023-11-04 12:48:31 24 4
gpt4 key购买 nike

我正在为 OCP 考试做一些练习。目前,我尝试打印 CopyOnWriteArrayList内容当使用多个线程时。根据文档,CopyOnWriteArrayList 的迭代器将

print the numbers in the list which are present at the moment the iterator is created

因此,当在 CopyOnWriteArrayList 上启动一个线程写入并从 CopyOnWriteArrayList 开始另一个线程读取时,我希望(有时)打印出一些项目。当写入线程完成之后遍历 CopyOnWriteArrayList 时,我希望有一个新迭代器打印出所有项目

不幸的是,当使用Runnable接口(interface)的匿名实现时,这个不起作用。但它在使用自定义线程类时有效,其中我传递了对 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();
}

输出(有时 - 因为有线程) first read thread prints out some numbers, second read thread won't print out any numbers!

使用自定义线程类 - 按预期工作

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();
}

输出 - 按预期工作 first read thread prints out some numbers, second read thread prints out all numbers

目前我正在使用 Win10 计算机,配有 JDK 1.7.0_25 和 Eclipse Mars Release 4.5.0

最佳答案

正如@user2357112 所发布的,代码没有任何问题。该问题似乎与Eclipse 相关!

在 Eclipse Mars/JRE 1.7.0_25 中运行问题代码时,它不会打印出 0 到 9999 之间的数字。相反,它会立即退出,就好像没有新的迭代器一样。

我从命令行编译了代码,并使用java.exejavaw.exe启动它。两者都显示正确的输出。

java命令

java -classpath "c:\Chapter14\ConcurrentCollections\bin" concurrentCollections.TestClass

结果

Command line output - relevant pieces

javaw命令

javaw -classpath "c:\Chapter14\ConcurrentCollections\bin" concurrentCollections.TestClass > "c:\test.txt"

结果

test file contents - first xxx numbers - contains all numbers

现在我可以说(肯定)我的代码没有任何问题,JVM 也没有问题!

编辑

我通过修改运行配置将输出重定向到文件。在 eclipse 中重新启动应用程序。 Output.txt 包含所有数字 - 但在 Eclipse 的控制台窗口中(分配控制台),数字不会出现...

Run Configurations Eclipse

关于java - CopyOnWriteArrayList 上线程中的迭代器不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36072130/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com