假设标准 Java 应用程序遵循每个请求线程模型。
非线程安全是指当多个线程写入同一个容器时,会出错,像这样:
public void demo1() {
List<String> list = new ArrayList();
ExecutorService executor = Executors.newFixedThreadPool(6);
for (int i = 0; i < 100; i++) {
// just don't do this, it terrible
executor.submit(() -> {
list.add(UUID.randomUUID().toString());
});
}
}
但是如果一个线程编写自己的容器那就没问题。这是另一个例子。 这是现实生活中最常见的情况,每个请求都是一个独立的线程,因此不存在线程安全问题。
public void demo2() {
ExecutorService executor = Executors.newFixedThreadPool(6);
for (int i = 0; i < 100; i++) {
executor.submit(() -> {
// this is fine.
List<String> list = new ArrayList();
list.add(UUID.randomUUID().toString());
});
}
}
如果确实需要在多个线程中处理一个集合,JDK提供了一组线程安全的容器。例如,您可以使用
Vector
或 CopyOnWriteArrayList
来替换 ArrayList
,并使用 ConcurrentHashMap
来替换 HashMap
。
public void demo3() {
// "CopyOnWriteArrayList " is thread-safe
List<String> list = new CopyOnWriteArrayList();
ExecutorService executor = Executors.newFixedThreadPool(6);
for (int i = 0; i < 100; i++) {
// this is also fine
executor.submit(() -> {
list.add(UUID.randomUUID().toString());
});
}
}