dev*_*ull 4 java multithreading
我正在阅读CopyOnWriteArrayList并想知道如何在ArrayList课堂上展示数据竞赛.基本上我正在尝试模拟ArrayList失败的情况,以便有必要使用CopyOnWriteArrayList.关于如何模拟这个的任何建议.
竞争是两个(或更多)线程尝试对共享数据进行操作,最终输出取决于访问数据的顺序(并且该顺序是不确定的)
来自维基百科:
竞赛条件或竞赛危险是电子系统或过程中的缺陷,其中过程的输出和/或结果出乎意料地且严重地取决于其他事件的顺序或时间.该术语起源于两个信号相互竞争以首先影响输出的想法.
例如:
public class Test {
private static List<String> list = new CopyOnWriteArrayList<String>();
public static void main(String[] args) throws Exception {
ExecutorService e = Executors.newFixedThreadPool(5);
e.execute(new WriterTask());
e.execute(new WriterTask());
e.execute(new WriterTask());
e.execute(new WriterTask());
e.execute(new WriterTask());
e.awaitTermination(20, TimeUnit.SECONDS);
}
static class WriterTask implements Runnable {
@Override
public void run() {
for (int i = 0; i < 25000; i ++) {
list.add("a");
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是,使用时ArrayList,这会失败ArrayIndexOutOfbounds.这是因为在插入之前ensureCapacity(..)应该调用它以确保内部数组可以保存新数据.以下是发生的事情:
add(..),然后调用ensureCapacity(currentSize + 1)ensureCapacity(currentSize + 1).currentSize,内部数组的新大小是currentSize + 1array[size++].第一个成功,第二个失败,因为内部阵列由于接收条件而没有正确扩展.发生这种情况,因为两个线程试图在同一个结构上同时添加项目,并且添加其中一个已覆盖另一个(即第一个丢失)
另一个好处 CopyOnWriteArrayList
ArrayListArrayList.它肯定会得到ConcurrentModificationException以下是如何演示它:
public class Test {
private static List<String> list = new ArrayList<String>();
public static void main(String[] args) throws Exception {
ExecutorService e = Executors.newFixedThreadPool(2);
e.execute(new WriterTask());
e.execute(new ReaderTask());
}
static class ReaderTask implements Runnable {
@Override
public void run() {
while (true) {
for (String s : list) {
System.out.println(s);
}
}
}
}
static class WriterTask implements Runnable {
@Override
public void run() {
while(true) {
list.add("a");
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果你运行这个程序多次,你经常会越来越ConcurrentModificationException 之前你OutOfMemoryError.
如果你替换它CopyOnWriteArrayList,你没有得到异常(但程序很慢)
请注意,这只是一个演示 - CopyOnWriteArrayList当读取次数大大超过写入次数时,这样做的好处是.