2026/4/10 13:26:03
网站建设
项目流程
网站后台选择,建一个门户网站多少钱,淘宝网店模板,包装回收网站建设在 Java 中#xff0c;Collections.synchronizedList、CopyOnWriteArrayList 和 synchronized 都可以用来解决多线程环境下的线程安全问题#xff0c;但它们的性能和适用场景有所不同。以下是三者的区别和性能对比#xff1a;1. Collections.synchronizedListCollections.sy…在 Java 中Collections.synchronizedList、CopyOnWriteArrayList和synchronized都可以用来解决多线程环境下的线程安全问题但它们的性能和适用场景有所不同。以下是三者的区别和性能对比1.Collections.synchronizedListCollections.synchronizedList是通过对ArrayList进行包装使用同步锁synchronized来保证线程安全。工作原理Collections.synchronizedList在每个方法如add、get等上都加了同步锁确保同一时间只有一个线程可以操作该集合。优点线程安全适用于多线程环境。简单易用直接通过Collections.synchronizedList包装即可。缺点性能较低由于每次操作都需要获取锁多个线程同时访问时会产生锁竞争性能会下降。迭代器不安全在使用迭代器遍历时仍需要手动同步否则可能抛出ConcurrentModificationException。示例代码ListString list Collections.synchronizedList(new ArrayList()); synchronized (list) { // 遍历时需要手动加锁 for (String item : list) { System.out.println(item); } }适用场景适合读写操作比例相对均衡的场景。适合对线程安全要求较高但性能要求不高的场景。2.CopyOnWriteArrayListCopyOnWriteArrayList是一种线程安全的集合它的实现方式是写时复制。工作原理每次对集合进行写操作如add、remove等时会复制一份底层数组修改完成后再将新的数组替换旧的数组。读操作不需要加锁因为底层数组是只读的读操作不会影响数据一致性。优点读操作性能高读操作不需要加锁多个线程可以同时读取数据。线程安全写操作通过复制数组实现避免了锁竞争。迭代器安全迭代器是基于快照的不会抛出ConcurrentModificationException。缺点写操作性能较低每次写操作都会复制整个数组开销较大。内存占用高频繁的写操作会导致大量的内存分配和垃圾回收。示例代码ListString list new CopyOnWriteArrayList(); list.add(A); list.add(B); for (String item : list) { // 迭代时不需要加锁 System.out.println(item); }适用场景适合读多写少的场景例如缓存、配置管理等。不适合频繁写操作的场景。3.synchronizedsynchronized是 Java 提供的关键字用于显式地对代码块或方法加锁。工作原理synchronized可以用来锁住代码块或方法确保同一时间只有一个线程可以执行被锁住的代码。优点灵活性高可以精确控制锁的范围。线程安全通过锁机制保证线程安全。缺点性能较低锁的粒度较大容易导致线程阻塞和性能下降。代码复杂度高需要手动管理锁的范围容易出错。示例代码ListString list new ArrayList(); synchronized (list) { list.add(A); list.add(B); }适用场景适合需要对代码块或方法进行精细化控制的场景。不适合需要频繁操作集合的场景容易导致性能瓶颈。性能对比特性Collections.synchronizedListCopyOnWriteArrayListsynchronized线程安全性是是是读操作性能中等需要加锁高无锁低需要加锁写操作性能中等需要加锁低写时复制开销大低需要加锁迭代器安全性不安全需手动加锁安全基于快照不安全需手动加锁适用场景读写均衡场景读多写少场景灵活控制锁的场景内存占用低高写时复制会占用更多内存低总结Collections.synchronizedList适合读写操作均衡的场景。性能一般但实现简单。CopyOnWriteArrayList适合读多写少的场景。读操作性能高但写操作性能较低内存占用较高。synchronized适合需要精确控制锁的场景。性能较低代码复杂度较高。选择建议如果你的场景是读多写少推荐使用CopyOnWriteArrayList。如果你的场景是读写均衡推荐使用Collections.synchronizedList。如果需要对代码块进行精细化的线程安全控制使用synchronized。测试代码public class ListTest { private static void synchronizedTest() throws InterruptedException { long start System.currentTimeMillis(); /** * ArrayList 是非线程安全的多个线程同时操作时可能导致索引越界。 * * Exception in thread Thread-20 java.lang.ArrayIndexOutOfBoundsException: 10 * at java.util.ArrayList.add(ArrayList.java:465) */ ListString list new ArrayList(); int threadCount 1000; CountDownLatch countDownLatch new CountDownLatch(threadCount); for (int i 0; i threadCount; i) { new Thread(() - { try { Thread.sleep(500); } catch (InterruptedException e) { throw new RuntimeException(e); } // 626, 617 synchronized (list) { list.add(1); } countDownLatch.countDown(); }).start(); } countDownLatch.await(); System.out.println(list.size() list.size() 耗时 (System.currentTimeMillis() - start)); for (String content : list) { System.out.println(content: content); } } private static void synchronizedListTest() throws InterruptedException { long start System.currentTimeMillis(); /** * ArrayList 是非线程安全的多个线程同时操作时可能导致索引越界。 * * Exception in thread Thread-20 java.lang.ArrayIndexOutOfBoundsException: 10 * at java.util.ArrayList.add(ArrayList.java:465) */ ListString list Collections.synchronizedList(new ArrayList());// 622 int threadCount 1000; CountDownLatch countDownLatch new CountDownLatch(threadCount); for (int i 0; i threadCount; i) { new Thread(() - { try { Thread.sleep(500); } catch (InterruptedException e) { throw new RuntimeException(e); } list.add(1); countDownLatch.countDown(); }).start(); } countDownLatch.await(); System.out.println(list.size() list.size() 耗时 (System.currentTimeMillis() - start)); for (String content : list) { System.out.println(content: content); } } private static void copyOnWriteArrayListTest() throws InterruptedException { long start System.currentTimeMillis(); /** * ArrayList 是非线程安全的多个线程同时操作时可能导致索引越界。 * * Exception in thread Thread-20 java.lang.ArrayIndexOutOfBoundsException: 10 * at java.util.ArrayList.add(ArrayList.java:465) */ ListString list new CopyOnWriteArrayList();// 622 int threadCount 1000; CountDownLatch countDownLatch new CountDownLatch(threadCount); for (int i 0; i threadCount; i) { new Thread(() - { try { Thread.sleep(500); } catch (InterruptedException e) { throw new RuntimeException(e); } list.add(1); countDownLatch.countDown(); }).start(); } countDownLatch.await(); System.out.println(list.size() list.size() 耗时 (System.currentTimeMillis() - start)); for (String content : list) { System.out.println(content: content); } } public static void main(String[] args) throws InterruptedException { synchronizedTest(); synchronizedListTest(); copyOnWriteArrayListTest(); }