并发容器与原子操作类
在Java并发编程中,并发容器
和原子操作类
是两个重要的概念。这些类可以帮助你处理多线程环境下的数据共享与操作,避免常见的线程安全问题。下面我们将详细讨论这些内容。
1. 并发容器
并发容器是为了解决在多线程环境中对数据结构的并发访问问题而设计的。Java提供了一系列的并发容器,这些容器大多数位于java.util.concurrent
包中。
1.1 ConcurrentHashMap
ConcurrentHashMap
是一个线程安全的哈希表,性能优于使用synchronized
关键字的传统哈希表。当多个线程同时访问ConcurrentHashMap
时,它会保证线程安全性。
使用示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| import java.util.concurrent.ConcurrentHashMap;
public class ConcurrentHashMapExample { public static void main(String[] args) { ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("A", 1); map.put("B", 2); Runnable task = () -> { for (int i = 0; i < 10; i++) { map.put(Thread.currentThread().getName() + i, i); } };
Thread t1 = new Thread(task); Thread t2 = new Thread(task); t1.start(); t2.start();
try { t1.join(); t2.join(); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println(map); } }
|
1.2 CopyOnWriteArrayList
CopyOnWriteArrayList
是一个线程安全的List实现,适合用于读多写少的场景。在写入操作时,它会创建数组的新副本。
使用示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| import java.util.List; import java.util.concurrent.CopyOnWriteArrayList;
public class CopyOnWriteArrayListExample { public static void main(String[] args) { List<String> list = new CopyOnWriteArrayList<>(); Runnable task = () -> { for (int i = 0; i < 5; i++) { list.add(Thread.currentThread().getName() + " - " + i); } };
Thread t1 = new Thread(task); Thread t2 = new Thread(task); t1.start(); t2.start();
try { t1.join(); t2.join(); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println(list); } }
|
1.3 BlockingQueue
BlockingQueue
是一种用于多线程间传递数据的队列。它提供了一些方法来支持阻塞的插入和删除操作。
使用示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue;
public class BlockingQueueExample { public static void main(String[] args) { BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10);
Thread producer = new Thread(() -> { try { for (int i = 0; i < 10; i++) { queue.put(i); System.out.println("Produced: " + i); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } });
Thread consumer = new Thread(() -> { try { for (int i = 0; i < 10; i++) { Integer value = queue.take(); System.out.println("Consumed: " + value); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } });
producer.start(); consumer.start(); } }
|
2. 原子操作类
原子操作类是提供对基本数据类型的原子操作的工具,位于java.util.concurrent.atomic
包中。它们可以在不使用同步
的情况下,保证对某个变量的原子性更新。
2.1 AtomicInteger
AtomicInteger
是一种能保证操作原子性的整型类,常用于计数器。
使用示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| import java.util.concurrent.atomic.AtomicInteger;
public class AtomicIntegerExample { public static void main(String[] args) { AtomicInteger atomicInt = new AtomicInteger(0);
Runnable task = () -> { for (int i = 0; i < 1000; i++) { atomicInt.incrementAndGet(); } };
Thread t1 = new Thread(task); Thread t2 = new Thread(task); t1.start(); t2.start();
try { t1.join(); t2.join(); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println("Final value: " + atomicInt.get()); } }
|
2.2 AtomicReference
AtomicReference
是一种能够保证操作原子性的引用类型,适用于需要在线程间共享对象的场景。
使用示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| import java.util.concurrent.atomic.AtomicReference;
public class AtomicReferenceExample { public static void main(String[] args) { AtomicReference<String> atomicRef = new AtomicReference<>("Initial");
Runnable task = () -> { String newValue = Thread.currentThread().getName(); atomicRef.set(newValue); System.out.println("Set to: " + newValue); };
Thread t1 = new Thread(task); Thread t2 = new Thread(task); t1.start(); t2.start();
try { t1.join(); t2.join(); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println("Final value: " + atomicRef.get()); } }
|
总结
在Java中,并发容器
和原子操作类
为多线程编程提供了强大的工具,能够有效减轻开发者在数据共享和安全性方面的负担。使用这些工具可以帮助你编写更高效、更安全的并发代码。理解这些结构与原理将对你的Java进阶学习产生深远的影响。