我理解fail-fast(LinkedList)和故障安全(copyonwrite)迭代器,但是弱的一致性仍然是个谜.
文档说它可能反映了底层集合的变化,但不能保证.因此,我认为弱一致性不会创建支持集合的副本.(在并发Map中,它在同一个bucketarray上工作).
我假设如果一个线程A创建了一个迭代器并且经过了一半,那么当线程B将一个项目放到数组开头的桶中时,这个更改对于线程A的迭代器是不可见的.
如果B将该项放到数组的末尾,A就会看到它.
是否可能有一个nosuchelement例外?
如果线程A创建一个迭代器,然后遍历到一个项目X,它有一个下一个项目Y,然后jvm停止线程A并恢复线程B,谁删除Y.这对线程A是否可见(我想是这样,否则并发映射将不会'是线程安全的,但对其迭代器的实现方式一无所知),因为它对线程A不可见,那么它很容易引发异常.
此代码来自Effective Java(Item 66):(没有sync或volatile,这永远不会结束)
public class ThreadPractice {
static boolean canrunstatic;
public static void main(String[] args) throws InterruptedException {
Thread backgroundThread = new Thread(new Runnable() {
public void run() {
int i = 0;
while (!canrunstatic){i++;}
System.out.println("finished");
}
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
canrunstatic = true;
}
Run Code Online (Sandbox Code Playgroud)
正如布洛赫在该章中提到的那样,它永远不会在控制台上写"完成".我一直在玩这个类,并将该行添加到runnable run方法:
System.out.println("im still running");
Run Code Online (Sandbox Code Playgroud)
有了这个,while循环不仅增加i,而且在每个循环中打印出这个字符串.但是什么让我发疯,这样线程在1秒后停止,当主线程从睡眠状态恢复时.
修改:(停止没有volatile/sync)
public class ThreadPractice {
static boolean canrunstatic;
public static void main(String[] args) throws InterruptedException {
Thread backgroundThread = new Thread(new Runnable() {
public void run() {
int i = …Run Code Online (Sandbox Code Playgroud)