- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在为 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();
}
使用自定义线程类 - 按预期工作
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();
}
目前我正在使用 Win10 计算机,配有 JDK 1.7.0_25 和 Eclipse Mars Release 4.5.0
最佳答案
正如@user2357112 所发布的,代码没有任何问题。该问题似乎与Eclipse 相关!
在 Eclipse Mars/JRE 1.7.0_25 中运行问题代码时,它不会打印出 0 到 9999 之间的数字。相反,它会立即退出,就好像没有新的迭代器一样。
我从命令行编译了代码,并使用java.exe
和javaw.exe
启动它。两者都显示正确的输出。
java命令
java -classpath "c:\Chapter14\ConcurrentCollections\bin" concurrentCollections.TestClass
结果
javaw命令
javaw -classpath "c:\Chapter14\ConcurrentCollections\bin" concurrentCollections.TestClass > "c:\test.txt"
结果
现在我可以说(肯定)我的代码没有任何问题,JVM 也没有问题!
编辑
我通过修改运行配置将输出重定向到文件。在 eclipse 中重新启动应用程序。 Output.txt
包含所有数字 - 但在 Eclipse 的控制台窗口中(分配控制台),数字不会出现...
关于java - CopyOnWriteArrayList 上线程中的迭代器不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36072130/
简述 选中类,执行Ctrl + alt + U 查看类的继承示意图如下: public class CopyOnWriteArrayList implements List, RandomAc
我目前正在使用 ExecutorService 在 CopyOnWrite ArrayLists 中发送批处理字符串以进行并行处理,其中处理这些列表的 Runnable 任务需要遍历列表并对每个字符串
我正在使用一个集合 CopyOnWriteArrayList myCOW = new CopyOnWriteArrayList(); 其中 X 是一个可变对象。我从 Java Concurr
许多列表实现都有一个选项来指定集合的初始容量,为什么 CopyOnWriteArrayList 不允许这样做? 最佳答案 在传统的ArrayList中,容量是在后备数组中保留更多空间的提示,以便稍
根据 CopyOnWriteArrayList JavaDoc: A thread-safe variant of java.util.ArrayList in which all mutative
可能很简单,但我自己无法弄清楚。我有一些 Spring Boot WebSockets 实现示例,并且想要显示总 Activity session 。所以我创建了@Scheduled activeSe
我有以下案例, public class Test { private static final int MAX_NUMBER = 10_00_00; public static vo
这个问题已经有答案了: In what situations is the CopyOnWriteArrayList suitable? [duplicate] (2 个回答) 已关闭 5 年前。 我
我从一些教程中理解了这个概念,只要我知道一个线程何时迭代列表,就允许其他线程修改底层列表,我们不会得到 ConcurrentModificationException(CME),但在 ArrayLis
CopyOnWriteArrayList 被标记为可序列化。但它的内部状态是短暂的。任何人都可以回答我们试图在这种类型的列表中序列化什么。 /** The array, accessed only v
根据 CopyOnWritearrayList 的 javadoc : A thread-safe variant of ArrayList in which all mutative operati
我想使用可以被多线程代码不断访问的数据结构。请让我知道 java 中的任何数据结构,我可以在其中等待并使用通知选项。请看下面的代码,为什么CDRemove的run方法不打印所有值 public cla
我需要将一些对象存储到数据库中。 首先 我将它们存储在内存中(存储在集合中) 当其中一个正确存储在数据库中时,我会将其删除 所以, public class AuditService { pr
我试图将 CopyOnWriteArrayList 理解为我的代码: 我的代码是: public class AuditService { private CopyOnWriteArrayLi
我正在为 OCP 考试做一些练习。目前,我尝试打印 CopyOnWriteArrayList 的内容当使用多个线程时。根据文档,CopyOnWriteArrayList 的迭代器将 print the
拥有一个映射,按类型作为键保存同一事件的事件监听器列表, func_1() 将开始从映射中获取一种类型的监听器列表,并迭代该列表以处理每个监听器的事件。 当一个监听器完成处理后,它会要求将其从 map
我查看了 OpenJDK source code的CopyOnWriteArrayList似乎所有写操作都受到同一个锁的保护,而读操作则根本不 protected 。据我了解,在 JMM 下,对变量的
我想在内部了解并发修改异常是如何在并发集合中处理的,例如 ConcurrentHashMap 和 CopyOnWriteArrayList。 网上有很多博客建议使用这两种数据结构来避免并发修改异常。但
CopyOnWriteArrayList 的 Javadocs 说 A thread-safe variant of ArrayList in which all mutative operation
我查看了 OpenJDK source code的 CopyOnWriteArrayList似乎所有的写操作都受到同一个锁的保护,而读操作根本不 protected 。据我了解,在 JMM 下,对变量
我是一名优秀的程序员,十分优秀!