J J*_*ohn 2 java parallel-processing multithreading java-8
我对以下代码感到困惑
public static void main(String[] args) throws InterruptedException
{
Integer[] intArray = {1, 2, 3, 4, 5, 6, 7, 8};
List<Integer> listOfIntegers =
new ArrayList<>(Arrays.asList(intArray));
List<Integer> parallelStorage = new ArrayList<>();//Collections.synchronizedList(new ArrayList<>());
listOfIntegers
.parallelStream()
// Don't do this! It uses a stateful lambda expression.
.map(e -> {
parallelStorage.add(e);
return e;
})
.forEachOrdered(e -> System.out.print(e + " "));
System.out.println();
parallelStorage
.stream()
.forEachOrdered(e -> System.out.print(e + " "));
System.out.println();
System.out.println("Sleep 5 sec");
TimeUnit.SECONDS.sleep(5);
parallelStorage
.stream()
.forEachOrdered(e -> System.out.print(e + " "));
}
Run Code Online (Sandbox Code Playgroud)
EveryTime执行它我得到了不同的结果,这让我很困惑,这里有一些结果:
Result 1:
1 2 3 4 5 6 7 8
null 3 8 7 1 4 5 6
Sleep 5 sec
null 3 8 7 1 4 5 6
Result 2?
1 2 3 4 5 6 7 8
6 2 4 1 5 7 8
Sleep 5 sec
6 2 4 1 5 7 8
Run Code Online (Sandbox Code Playgroud)
这有两个问题:
Q1:为什么parallelStorage的大小不确定?
我理解parallelStream使用fork/join框架,所以我猜这个问题是由一些线程没有完成他们的工作引起的,然后我暂停了主线程5秒,但似乎没有帮助,parallelStorage的大小仍保持不变;
Q2:为什么parallelStorage中存在null元素?
ArrayList不是线程安全的.这意味着如果你有两个线程同时更新列表,那么两个线程可能会以可能导致数据丢失的方式相互干扰(或者,对于某些数据结构,可能会完全破坏结构).
我不知道添加到a时所采取的步骤的确切顺序ArrayList,但让我们说它是这样的.一个ArrayList应包含背衬阵列,并且一个实例变量,指示当前大小是什么
Narr[N]NN以数组大小存储现在假设你有两个线程这样做.由于没有同步,如果线程同时调用,则线程可以按此顺序执行以下步骤add:
Read the array size into N
Read the array size into N
Put the new element in arr[N]
Put the new element in arr[N]
Add 1 to N
Add 1 to N
Store N into the array size
Store N into the array size
Run Code Online (Sandbox Code Playgroud)
如果在线程调用之前数组大小为3 add,请注意两个线程将3读入它们自己的局部变量N; 然后他们都将新元素放在同一个地方,然后将4存储到数组大小.因此,即使"添加"了两个元素,新的数组大小也将是4而不是5,并且其中一个新数据元素将丢失.
这就是你需要同步列表的原因.
(在多个线程之间完成步骤的方式是不可预测的.因此,在某些情况下,不同的执行顺序可能导致在存储元素之前两个线程增加大小,导致数组中的元素为因此,null请不要使用我在此处发布的步骤序列作为Java运行时所采取的实际步骤;这只是一个示例,我没有查看ArrayList代码.)
| 归档时间: |
|
| 查看次数: |
925 次 |
| 最近记录: |