Java并发编程实战指南
在现代软件开发中,并发编程已成为提升应用性能和响应能力的关键技术。Java作为企业级开发的主流语言,提供了丰富的并发编程工具和机制。本文将深入探讨Java并发编程的核心概念、实现技术和最佳实践。
并发编程基础概念
进程与线程
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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
|
public class ThreadBasics { static class MyThread extends Thread { private String threadName; public MyThread(String name) { this.threadName = name; } @Override public void run() { for (int i = 0; i < 5; i++) { System.out.println(threadName + " - 计数: " + i); try { Thread.sleep(1000); } catch (InterruptedException e) { System.out.println(threadName + " 被中断"); return; } } System.out.println(threadName + " 执行完成"); } } static class MyRunnable implements Runnable { private String taskName; public MyRunnable(String name) { this.taskName = name; } @Override public void run() { System.out.println(taskName + " 开始执行,线程: " + Thread.currentThread().getName()); try { Thread.sleep(2000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); return; } System.out.println(taskName + " 执行完成"); } } public static void main(String[] args) { MyThread thread1 = new MyThread("线程1"); thread1.start(); Thread thread2 = new Thread(new MyRunnable("任务1"), "工作线程"); thread2.start(); Thread thread3 = new Thread(() -> { System.out.println("Lambda线程执行: " + Thread.currentThread().getName()); }, "Lambda线程"); thread3.start(); try { thread1.join(); thread2.join(); thread3.join(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } System.out.println("所有线程执行完成"); } }
|
线程状态和生命周期
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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
|
public class ThreadStateMonitor { public static void main(String[] args) throws InterruptedException { Thread worker = new Thread(() -> { try { System.out.println("工作线程开始执行"); for (int i = 0; i < 3; i++) { System.out.println("工作中... " + i); Thread.sleep(1000); } synchronized (ThreadStateMonitor.class) { System.out.println("进入等待状态"); ThreadStateMonitor.class.wait(2000); } System.out.println("工作线程完成"); } catch (InterruptedException e) { System.out.println("工作线程被中断"); Thread.currentThread().interrupt(); } }, "WorkerThread"); Thread monitor = new Thread(() -> { while (worker.isAlive()) { System.out.println("线程状态: " + worker.getState()); try { Thread.sleep(500); } catch (InterruptedException e) { break; } } System.out.println("最终状态: " + worker.getState()); }, "MonitorThread"); System.out.println("启动前状态: " + worker.getState()); monitor.start(); worker.start(); Thread.sleep(4000); synchronized (ThreadStateMonitor.class) { ThreadStateMonitor.class.notifyAll(); } worker.join(); monitor.join(); } }
|
同步机制与锁
synchronized关键字
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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
|
public class SynchronizedExample { private int counter = 0; private final Object lock = new Object(); public synchronized void incrementMethod() { counter++; System.out.println("方法同步 - 计数器: " + counter + ", 线程: " + Thread.currentThread().getName()); } public void incrementBlock() { synchronized (this) { counter++; System.out.println("代码块同步 - 计数器: " + counter + ", 线程: " + Thread.currentThread().getName()); } } public void incrementWithCustomLock() { synchronized (lock) { counter++; System.out.println("自定义锁 - 计数器: " + counter + ", 线程: " + Thread.currentThread().getName()); } } public static synchronized void staticSyncMethod() { System.out.println("静态同步方法 - 线程: " + Thread.currentThread().getName()); } public static void main(String[] args) throws InterruptedException { SynchronizedExample example = new SynchronizedExample(); Thread[] threads = new Thread[5]; for (int i = 0; i < threads.length; i++) { final int threadNum = i; threads[i] = new Thread(() -> { for (int j = 0; j < 3; j++) { switch (j % 3) { case 0: example.incrementMethod(); break; case 1: example.incrementBlock(); break; case 2: example.incrementWithCustomLock(); break; } try { Thread.sleep(100); } catch (InterruptedException e) { Thread.currentThread().interrupt(); return; } } }, "Thread-" + threadNum); } for (Thread thread : threads) { thread.start(); } for (Thread thread : threads) { thread.join(); } System.out.println("最终计数器值: " + example.counter); } }
|
ReentrantLock显式锁
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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
| import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.Condition; import java.util.concurrent.TimeUnit;
public class ReentrantLockExample { private final ReentrantLock lock = new ReentrantLock(true); private final Condition condition = lock.newCondition(); private int sharedResource = 0; private boolean ready = false; public void basicLockUsage() { lock.lock(); try { sharedResource++; System.out.println("基本锁操作 - 资源值: " + sharedResource + ", 线程: " + Thread.currentThread().getName()); } finally { lock.unlock(); } } public void tryLockUsage() { if (lock.tryLock()) { try { sharedResource += 2; System.out.println("尝试锁成功 - 资源值: " + sharedResource + ", 线程: " + Thread.currentThread().getName()); Thread.sleep(1000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { lock.unlock(); } } else { System.out.println("尝试锁失败 - 线程: " + Thread.currentThread().getName()); } } public void tryLockWithTimeout() { try { if (lock.tryLock(2, TimeUnit.SECONDS)) { try { sharedResource += 3; System.out.println("超时锁成功 - 资源值: " + sharedResource + ", 线程: " + Thread.currentThread().getName()); } finally { lock.unlock(); } } else { System.out.println("超时锁失败 - 线程: " + Thread.currentThread().getName()); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } public void producer() { lock.lock(); try { while (ready) { condition.await(); } sharedResource = (int) (Math.random() * 100); ready = true; System.out.println("生产者生产: " + sharedResource + ", 线程: " + Thread.currentThread().getName()); condition.signalAll(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { lock.unlock(); } } public void consumer() { lock.lock(); try { while (!ready) { condition.await(); } System.out.println("消费者消费: " + sharedResource + ", 线程: " + Thread.currentThread().getName()); ready = false; condition.signalAll(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { lock.unlock(); } } public void printLockInfo() { System.out.println("锁信息:"); System.out.println(" 是否被锁定: " + lock.isLocked()); System.out.println(" 是否公平锁: " + lock.isFair()); System.out.println(" 等待队列长度: " + lock.getQueueLength()); System.out.println(" 持有锁次数: " + lock.getHoldCount()); } public static void main(String[] args) throws InterruptedException { ReentrantLockExample example = new ReentrantLockExample(); System.out.println("=== 基本锁操作测试 ==="); Thread[] basicThreads = new Thread[3]; for (int i = 0; i < basicThreads.length; i++) { basicThreads[i] = new Thread(example::basicLockUsage, "Basic-" + i); basicThreads[i].start(); } for (Thread thread : basicThreads) { thread.join(); } System.out.println("\n=== 尝试锁测试 ==="); Thread[] tryThreads = new Thread[3]; for (int i = 0; i < tryThreads.length; i++) { tryThreads[i] = new Thread(example::tryLockUsage, "Try-" + i); tryThreads[i].start(); } for (Thread thread : tryThreads) { thread.join(); } System.out.println("\n=== 生产者消费者测试 ==="); Thread producer = new Thread(example::producer, "Producer"); Thread consumer = new Thread(example::consumer, "Consumer"); producer.start(); consumer.start(); producer.join(); consumer.join(); example.printLockInfo(); } }
|
线程池与执行器框架
ThreadPoolExecutor详解
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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
| import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger;
public class ThreadPoolExample { static class CustomThreadFactory implements ThreadFactory { private final AtomicInteger threadNumber = new AtomicInteger(1); private final String namePrefix; public CustomThreadFactory(String namePrefix) { this.namePrefix = namePrefix; } @Override public Thread newThread(Runnable r) { Thread thread = new Thread(r, namePrefix + "-" + threadNumber.getAndIncrement()); thread.setDaemon(false); thread.setPriority(Thread.NORM_PRIORITY); return thread; } } static class CustomRejectedExecutionHandler implements RejectedExecutionHandler { @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { System.out.println("任务被拒绝: " + r.toString() + ", 线程池状态: " + executor.toString()); try { if (!executor.getQueue().offer(r, 1, TimeUnit.SECONDS)) { System.out.println("重新提交失败,任务丢弃"); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } static class WorkTask implements Runnable { private final int taskId; private final int duration; public WorkTask(int taskId, int duration) { this.taskId = taskId; this.duration = duration; } @Override public void run() { System.out.println("任务 " + taskId + " 开始执行,线程: " + Thread.currentThread().getName()); try { Thread.sleep(duration); } catch (InterruptedException e) { System.out.println("任务 " + taskId + " 被中断"); Thread.currentThread().interrupt(); return; } System.out.println("任务 " + taskId + " 执行完成,耗时: " + duration + "ms"); } @Override public String toString() { return "WorkTask{taskId=" + taskId + ", duration=" + duration + "}"; } } public static void main(String[] args) throws InterruptedException { ThreadPoolExecutor executor = new ThreadPoolExecutor( 2, 4, 60L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(3), new CustomThreadFactory("Worker"), new CustomRejectedExecutionHandler() ); ScheduledExecutorService monitor = Executors.newScheduledThreadPool(1); monitor.scheduleAtFixedRate(() -> { System.out.println("线程池状态 - " + "活跃线程: " + executor.getActiveCount() + ", 池大小: " + executor.getPoolSize() + ", 队列大小: " + executor.getQueue().size() + ", 完成任务: " + executor.getCompletedTaskCount()); }, 0, 1, TimeUnit.SECONDS); System.out.println("=== 提交任务 ==="); for (int i = 1; i <= 10; i++) { WorkTask task = new WorkTask(i, 2000 + (int)(Math.random() * 1000)); try { executor.submit(task); System.out.println("提交任务 " + i); } catch (RejectedExecutionException e) { System.out.println("任务 " + i + " 提交失败: " + e.getMessage()); } Thread.sleep(200); } Thread.sleep(8000); System.out.println("\n=== 关闭线程池 ==="); executor.shutdown(); try { if (!executor.awaitTermination(5, TimeUnit.SECONDS)) { System.out.println("强制关闭线程池"); executor.shutdownNow(); } } catch (InterruptedException e) { executor.shutdownNow(); Thread.currentThread().interrupt(); } monitor.shutdown(); System.out.println("程序结束"); } }
|
常用线程池类型
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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
| import java.util.concurrent.*; import java.util.List; import java.util.ArrayList;
public class ExecutorServiceTypes { static class TestTask implements Callable<String> { private final String taskName; private final int sleepTime; public TestTask(String taskName, int sleepTime) { this.taskName = taskName; this.sleepTime = sleepTime; } @Override public String call() throws Exception { System.out.println(taskName + " 开始执行,线程: " + Thread.currentThread().getName()); Thread.sleep(sleepTime); String result = taskName + " 完成,耗时: " + sleepTime + "ms"; System.out.println(result); return result; } } public static void testFixedThreadPool() throws InterruptedException { System.out.println("=== FixedThreadPool 测试 ==="); ExecutorService executor = Executors.newFixedThreadPool(3); List<Future<String>> futures = new ArrayList<>(); for (int i = 1; i <= 6; i++) { Future<String> future = executor.submit( new TestTask("Fixed-Task-" + i, 1000)); futures.add(future); } for (Future<String> future : futures) { try { String result = future.get(); System.out.println("结果: " + result); } catch (ExecutionException e) { System.out.println("任务执行异常: " + e.getCause()); } } executor.shutdown(); executor.awaitTermination(5, TimeUnit.SECONDS); } public static void testCachedThreadPool() throws InterruptedException { System.out.println("\n=== CachedThreadPool 测试 ==="); ExecutorService executor = Executors.newCachedThreadPool(); for (int i = 1; i <= 5; i++) { executor.submit(new TestTask("Cached-Task-" + i, 500)); } Thread.sleep(2000); for (int i = 6; i <= 8; i++) { executor.submit(new TestTask("Cached-Task-" + i, 500)); } executor.shutdown(); executor.awaitTermination(5, TimeUnit.SECONDS); } public static void testSingleThreadExecutor() throws InterruptedException { System.out.println("\n=== SingleThreadExecutor 测试 ==="); ExecutorService executor = Executors.newSingleThreadExecutor(); for (int i = 1; i <= 4; i++) { executor.submit(new TestTask("Single-Task-" + i, 800)); } executor.shutdown(); executor.awaitTermination(10, TimeUnit.SECONDS); } public static void testScheduledThreadPool() throws InterruptedException { System.out.println("\n=== ScheduledThreadPool 测试 ==="); ScheduledExecutorService executor = Executors.newScheduledThreadPool(2); System.out.println("提交延迟任务,当前时间: " + System.currentTimeMillis()); executor.schedule(() -> { System.out.println("延迟任务执行,时间: " + System.currentTimeMillis()); }, 2, TimeUnit.SECONDS); ScheduledFuture<?> periodicTask = executor.scheduleAtFixedRate(() -> { System.out.println("周期任务执行,时间: " + System.currentTimeMillis() + ", 线程: " + Thread.currentThread().getName()); }, 1, 1, TimeUnit.SECONDS); Thread.sleep(5000); periodicTask.cancel(false); executor.shutdown(); executor.awaitTermination(2, TimeUnit.SECONDS); } public static void testWorkStealingPool() throws InterruptedException { System.out.println("\n=== WorkStealingPool 测试 ==="); ExecutorService executor = Executors.newWorkStealingPool(); List<Future<String>> futures = new ArrayList<>(); int[] durations = {3000, 1000, 2000, 500, 1500, 800, 2500, 600}; for (int i = 0; i < durations.length; i++) { Future<String> future = executor.submit( new TestTask("Stealing-Task-" + (i + 1), durations[i])); futures.add(future); } for (Future<String> future : futures) { try { String result = future.get(); System.out.println("结果: " + result); } catch (ExecutionException e) { System.out.println("任务执行异常: " + e.getCause()); } } executor.shutdown(); executor.awaitTermination(10, TimeUnit.SECONDS); } public static void main(String[] args) throws InterruptedException { testFixedThreadPool(); testCachedThreadPool(); testSingleThreadExecutor(); testScheduledThreadPool(); testWorkStealingPool(); System.out.println("\n所有测试完成"); } }
|
并发工具类
CountDownLatch和CyclicBarrier
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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
| import java.util.concurrent.*; import java.util.Random;
public class ConcurrencyUtilities { public static void countDownLatchExample() throws InterruptedException { System.out.println("=== CountDownLatch 示例 ==="); int workerCount = 5; CountDownLatch startSignal = new CountDownLatch(1); CountDownLatch doneSignal = new CountDownLatch(workerCount); for (int i = 1; i <= workerCount; i++) { new Thread(new Worker(i, startSignal, doneSignal)).start(); } System.out.println("主线程准备工作..."); Thread.sleep(1000); System.out.println("发出开始信号"); startSignal.countDown(); System.out.println("等待所有工作线程完成..."); doneSignal.await(); System.out.println("所有工作完成,主线程继续执行"); } static class Worker implements Runnable { private final int workerId; private final CountDownLatch startSignal; private final CountDownLatch doneSignal; public Worker(int workerId, CountDownLatch startSignal, CountDownLatch doneSignal) { this.workerId = workerId; this.startSignal = startSignal; this.doneSignal = doneSignal; } @Override public void run() { try { System.out.println("工作者 " + workerId + " 等待开始信号"); startSignal.await(); int workTime = 1000 + new Random().nextInt(2000); System.out.println("工作者 " + workerId + " 开始工作,预计耗时: " + workTime + "ms"); Thread.sleep(workTime); System.out.println("工作者 " + workerId + " 完成工作"); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { doneSignal.countDown(); } } } public static void cyclicBarrierExample() throws InterruptedException { System.out.println("\n=== CyclicBarrier 示例 ==="); int participantCount = 4; CyclicBarrier barrier = new CyclicBarrier(participantCount, () -> { System.out.println("*** 所有参与者到达屏障,执行汇总任务 ***"); }); for (int i = 1; i <= participantCount; i++) { new Thread(new Participant(i, barrier)).start(); } Thread.sleep(8000); } static class Participant implements Runnable { private final int participantId; private final CyclicBarrier barrier; public Participant(int participantId, CyclicBarrier barrier) { this.participantId = participantId; this.barrier = barrier; } @Override public void run() { try { System.out.println("参与者 " + participantId + " 开始第一阶段工作"); Thread.sleep(1000 + new Random().nextInt(1000)); System.out.println("参与者 " + participantId + " 完成第一阶段,等待其他参与者"); barrier.await(); System.out.println("参与者 " + participantId + " 开始第二阶段工作"); Thread.sleep(800 + new Random().nextInt(800)); System.out.println("参与者 " + participantId + " 完成第二阶段,等待其他参与者"); barrier.await(); System.out.println("参与者 " + participantId + " 所有工作完成"); } catch (InterruptedException | BrokenBarrierException e) { System.out.println("参与者 " + participantId + " 被中断: " + e.getMessage()); Thread.currentThread().interrupt(); } } } public static void main(String[] args) throws InterruptedException { countDownLatchExample(); cyclicBarrierExample(); } }
|
Semaphore信号量
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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
| import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; import java.util.Random;
public class SemaphoreExample { static class ResourcePool { private final Semaphore semaphore; private final String[] resources; private final boolean[] used; public ResourcePool(int size) { this.semaphore = new Semaphore(size, true); this.resources = new String[size]; this.used = new boolean[size]; for (int i = 0; i < size; i++) { resources[i] = "Resource-" + (i + 1); } } public String acquireResource() throws InterruptedException { semaphore.acquire(); return getResource(); } public String tryAcquireResource(long timeout, TimeUnit unit) throws InterruptedException { if (semaphore.tryAcquire(timeout, unit)) { return getResource(); } return null; } private synchronized String getResource() { for (int i = 0; i < resources.length; i++) { if (!used[i]) { used[i] = true; System.out.println("获取资源: " + resources[i] + ", 剩余许可: " + semaphore.availablePermits()); return resources[i]; } } return null; } public void releaseResource(String resource) { if (returnResource(resource)) { semaphore.release(); } } private synchronized boolean returnResource(String resource) { for (int i = 0; i < resources.length; i++) { if (resources[i].equals(resource) && used[i]) { used[i] = false; System.out.println("释放资源: " + resource + ", 可用许可: " + semaphore.availablePermits()); return true; } } return false; } public void printStatus() { System.out.println("资源池状态 - 可用许可: " + semaphore.availablePermits() + ", 等待队列长度: " + semaphore.getQueueLength()); } } static class ResourceUser implements Runnable { private final int userId; private final ResourcePool pool; public ResourceUser(int userId, ResourcePool pool) { this.userId = userId; this.pool = pool; } @Override public void run() { try { System.out.println("用户 " + userId + " 尝试获取资源"); String resource = pool.tryAcquireResource(2, TimeUnit.SECONDS); if (resource != null) { System.out.println("用户 " + userId + " 获取到资源: " + resource); int useTime = 1000 + new Random().nextInt(2000); System.out.println("用户 " + userId + " 使用资源 " + resource + ", 预计使用时间: " + useTime + "ms"); Thread.sleep(useTime); pool.releaseResource(resource); System.out.println("用户 " + userId + " 释放资源: " + resource); } else { System.out.println("用户 " + userId + " 获取资源超时"); } } catch (InterruptedException e) { System.out.println("用户 " + userId + " 被中断"); Thread.currentThread().interrupt(); } } } static class RateLimiter { private final Semaphore semaphore; public RateLimiter(int permitsPerSecond) { this.semaphore = new Semaphore(permitsPerSecond); Thread replenisher = new Thread(() -> { while (!Thread.currentThread().isInterrupted()) { try { Thread.sleep(1000); int currentPermits = semaphore.availablePermits(); int toAdd = permitsPerSecond - currentPermits; if (toAdd > 0) { semaphore.release(toAdd); System.out.println("补充许可: " + toAdd + ", 当前可用: " + semaphore.availablePermits()); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; } } }); replenisher.setDaemon(true); replenisher.start(); } public boolean tryAcquire() { return semaphore.tryAcquire(); } public void acquire() throws InterruptedException { semaphore.acquire(); } } public static void main(String[] args) throws InterruptedException { System.out.println("=== 资源池测试 ==="); ResourcePool pool = new ResourcePool(3); Thread[] users = new Thread[6]; for (int i = 1; i <= users.length; i++) { users[i - 1] = new Thread(new ResourceUser(i, pool), "User-" + i); } for (Thread user : users) { user.start(); Thread.sleep(200); } for (int i = 0; i < 10; i++) { Thread.sleep(1000); pool.printStatus(); } for (Thread user : users) { user.join(); } System.out.println("\n=== 限流器测试 ==="); RateLimiter limiter = new RateLimiter(3); for (int i = 1; i <= 10; i++) { final int requestId = i; new Thread(() -> { try { if (limiter.tryAcquire()) { System.out.println("请求 " + requestId + " 通过限流,时间: " + System.currentTimeMillis()); } else { System.out.println("请求 " + requestId + " 被限流"); } } catch (Exception e) { e.printStackTrace(); } }).start(); Thread.sleep(300); } Thread.sleep(5000); System.out.println("测试完成"); } }
|
原子类与CAS操作
原子变量使用
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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
| import java.util.concurrent.atomic.*; import java.util.concurrent.CountDownLatch;
public class AtomicExample { private static final AtomicInteger counter = new AtomicInteger(0); private static final AtomicLong longCounter = new AtomicLong(0); private static final AtomicBoolean flag = new AtomicBoolean(false); private static final AtomicReference<String> atomicString = new AtomicReference<>("initial"); private static final AtomicIntegerArray atomicArray = new AtomicIntegerArray(10); private static final AtomicIntegerFieldUpdater<AtomicExample> scoreUpdater = AtomicIntegerFieldUpdater.newUpdater(AtomicExample.class, "score"); private volatile int score = 0; public static void basicAtomicOperations() throws InterruptedException { System.out.println("=== 基本原子操作 ==="); int threadCount = 5; int incrementsPerThread = 1000; CountDownLatch latch = new CountDownLatch(threadCount); for (int i = 0; i < threadCount; i++) { new Thread(() -> { for (int j = 0; j < incrementsPerThread; j++) { counter.incrementAndGet(); longCounter.addAndGet(2); String current = atomicString.get(); String newValue = current + "."; while (!atomicString.compareAndSet(current, newValue)) { current = atomicString.get(); newValue = current + "."; } } latch.countDown(); }, "Worker-" + i).start(); } latch.await(); System.out.println("Counter 最终值: " + counter.get()); System.out.println("Long Counter 最终值: " + longCounter.get()); System.out.println("String 长度: " + atomicString.get().length()); System.out.println("期望 Counter 值: " + (threadCount * incrementsPerThread)); } public static void atomicArrayOperations() throws InterruptedException { System.out.println("\n=== 原子数组操作 ==="); int threadCount = 3; CountDownLatch latch = new CountDownLatch(threadCount); for (int i = 0; i < atomicArray.length(); i++) { atomicArray.set(i, i * 10); } System.out.println("初始数组: " + java.util.Arrays.toString( java.util.stream.IntStream.range(0, atomicArray.length()) .map(atomicArray::get).toArray())); for (int i = 0; i < threadCount; i++) { final int threadId = i; new Thread(() -> { for (int j = 0; j < atomicArray.length(); j++) { atomicArray.incrementAndGet(j); int expected = atomicArray.get(j); while (!atomicArray.compareAndSet(j, expected, expected + threadId)) { expected = atomicArray.get(j); } } latch.countDown(); }, "ArrayWorker-" + i).start(); } latch.await(); System.out.println("最终数组: " + java.util.Arrays.toString( java.util.stream.IntStream.range(0, atomicArray.length()) .map(atomicArray::get).toArray())); } public void fieldUpdaterExample() throws InterruptedException { System.out.println("\n=== 字段更新器示例 ==="); int threadCount = 3; CountDownLatch latch = new CountDownLatch(threadCount); for (int i = 0; i < threadCount; i++) { new Thread(() -> { for (int j = 0; j < 100; j++) { scoreUpdater.incrementAndGet(this); } latch.countDown(); }, "ScoreWorker-" + i).start(); } latch.await(); System.out.println("最终分数: " + score); System.out.println("期望分数: " + (threadCount * 100)); } public static void abaProblemo() throws InterruptedException { System.out.println("\n=== ABA问题演示 ==="); AtomicReference<String> atomicRef = new AtomicReference<>("A"); AtomicStampedReference<String> stampedRef = new AtomicStampedReference<>("A", 0); Thread thread1 = new Thread(() -> { try { Thread.sleep(100); boolean success1 = atomicRef.compareAndSet("A", "B"); System.out.println("Thread1 A->B: " + success1); Thread.sleep(100); boolean success2 = atomicRef.compareAndSet("B", "A"); System.out.println("Thread1 B->A: " + success2); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }, "ABA-Thread1"); Thread thread2 = new Thread(() -> { try { String initial = atomicRef.get(); System.out.println("Thread2 读取初始值: " + initial); Thread.sleep(300); boolean success = atomicRef.compareAndSet("A", "C"); System.out.println("Thread2 A->C: " + success + " (发生了ABA问题,但CAS成功了)"); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }, "ABA-Thread2"); thread1.start(); thread2.start(); thread1.join(); thread2.join(); System.out.println("最终值: " + atomicRef.get()); System.out.println("\n使用AtomicStampedReference解决ABA问题:"); Thread thread3 = new Thread(() -> { try { int[] stampHolder = new int[1]; String ref = stampedRef.get(stampHolder); int stamp = stampHolder[0]; System.out.println("Thread3 读取: " + ref + ", 版本: " + stamp); Thread.sleep(300); boolean success = stampedRef.compareAndSet("A", "C", stamp, stamp + 1); System.out.println("Thread3 A->C: " + success + " (版本号不匹配,CAS失败)"); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }, "Stamped-Thread"); stampedRef.compareAndSet("A", "B", 0, 1); stampedRef.compareAndSet("B", "A", 1, 2); thread3.start(); thread3.join(); } public static void main(String[] args) throws InterruptedException { basicAtomicOperations(); atomicArrayOperations(); AtomicExample example = new AtomicExample(); example.fieldUpdaterExample(); abaProblemo(); } }
|
并发集合
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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
| import java.util.concurrent.*; import java.util.Map; import java.util.Random;
public class ConcurrentCollectionExample { public static void concurrentHashMapExample() throws InterruptedException { System.out.println("=== ConcurrentHashMap 示例 ==="); ConcurrentHashMap<String, Integer> concurrentMap = new ConcurrentHashMap<>(); int threadCount = 5; int operationsPerThread = 1000; CountDownLatch latch = new CountDownLatch(threadCount); for (int i = 0; i < threadCount; i++) { final int threadId = i; new Thread(() -> { Random random = new Random(); for (int j = 0; j < operationsPerThread; j++) { String key = "key-" + (random.nextInt(100) + 1); concurrentMap.compute(key, (k, v) -> (v == null) ? 1 : v + 1); if (j % 10 == 0) { concurrentMap.putIfAbsent("thread-" + threadId + "-" + j, j); } if (j % 20 == 0) { concurrentMap.replace(key, concurrentMap.get(key), concurrentMap.getOrDefault(key, 0) * 2); } } latch.countDown(); }, "MapWorker-" + i).start(); } latch.await(); System.out.println("Map 大小: " + concurrentMap.size()); System.out.println("前10个键值对:"); concurrentMap.entrySet().stream() .limit(10) .forEach(entry -> System.out.println(" " + entry.getKey() + " -> " + entry.getValue())); int sum = concurrentMap.values().parallelStream() .mapToInt(Integer::intValue) .sum(); System.out.println("所有值的总和: " + sum); concurrentMap.forEach(10, (key, value) -> { if (value > 50) { System.out.println("高频键: " + key + " = " + value); } }); } public static void concurrentQueueExample() throws InterruptedException { System.out.println("\n=== 并发队列示例 ==="); ConcurrentLinkedQueue<String> concurrentQueue = new ConcurrentLinkedQueue<>(); BlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<>(10); CountDownLatch producerLatch = new CountDownLatch(3); CountDownLatch consumerLatch = new CountDownLatch(2); for (int i = 1; i <= 3; i++) { final int producerId = i; new Thread(() -> { try { for (int j = 1; j <= 5; j++) { String item = "Producer-" + producerId + "-Item-" + j; concurrentQueue.offer(item); Integer number = producerId * 10 + j; blockingQueue.put(number); System.out.println("生产: " + item + ", 数字: " + number); Thread.sleep(100); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { producerLatch.countDown(); } }, "Producer-" + i).start(); } for (int i = 1; i <= 2; i++) { final int consumerId = i; new Thread(() -> { try { while (!Thread.currentThread().isInterrupted()) { String item = concurrentQueue.poll(); if (item != null) { System.out.println("消费者 " + consumerId + " 消费: " + item); } Integer number = blockingQueue.poll(1, TimeUnit.SECONDS); if (number != null) { System.out.println("消费者 " + consumerId + " 消费数字: " + number); } if (producerLatch.getCount() == 0 && concurrentQueue.isEmpty() && blockingQueue.isEmpty()) { break; } } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { consumerLatch.countDown(); } }, "Consumer-" + i).start(); } producerLatch.await(); consumerLatch.await(); System.out.println("队列操作完成"); System.out.println("剩余非阻塞队列元素: " + concurrentQueue.size()); System.out.println("剩余阻塞队列元素: " + blockingQueue.size()); } public static void copyOnWriteExample() throws InterruptedException { System.out.println("\n=== CopyOnWriteArrayList 示例 ==="); CopyOnWriteArrayList<String> cowList = new CopyOnWriteArrayList<>(); for (int i = 1; i <= 5; i++) { cowList.add("Initial-" + i); } CountDownLatch latch = new CountDownLatch(3); new Thread(() -> { try { for (int i = 1; i <= 3; i++) { cowList.add("Writer-" + i); System.out.println("写入: Writer-" + i + ", 当前大小: " + cowList.size()); Thread.sleep(500); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { latch.countDown(); } }, "Writer").start(); for (int i = 1; i <= 2; i++) { final int readerId = i; new Thread(() -> { try { for (int j = 0; j < 5; j++) { System.out.println("读者 " + readerId + " 读取列表:"); for (String item : cowList) { System.out.println(" " + item); } System.out.println("读者 " + readerId + " 读取完成,大小: " + cowList.size()); Thread.sleep(300); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { latch.countDown(); } }, "Reader-" + i).start(); } latch.await(); System.out.println("最终列表内容:"); cowList.forEach(item -> System.out.println(" " + item)); } public static void main(String[] args) throws InterruptedException { concurrentHashMapExample(); concurrentQueueExample(); copyOnWriteExample(); } }
|
性能优化与最佳实践
并发性能测试
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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
| import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.ReentrantLock;
public class ConcurrencyPerformance { public static void synchronizationPerformanceTest() throws InterruptedException { System.out.println("=== 同步机制性能对比 ==="); int threadCount = 10; int operationsPerThread = 100000; testSynchronized(threadCount, operationsPerThread); testReentrantLock(threadCount, operationsPerThread); testAtomicLong(threadCount, operationsPerThread); testNoSync(threadCount, operationsPerThread); } private static void testSynchronized(int threadCount, int operations) throws InterruptedException { class SyncCounter { private long count = 0; public synchronized void increment() { count++; } public synchronized long getCount() { return count; } } SyncCounter counter = new SyncCounter(); long startTime = System.nanoTime(); CountDownLatch latch = new CountDownLatch(threadCount); for (int i = 0; i < threadCount; i++) { new Thread(() -> { for (int j = 0; j < operations; j++) { counter.increment(); } latch.countDown(); }).start(); } latch.await(); long endTime = System.nanoTime(); System.out.println("Synchronized - 耗时: " + (endTime - startTime) / 1_000_000 + "ms, 结果: " + counter.getCount()); } private static void testReentrantLock(int threadCount, int operations) throws InterruptedException { class LockCounter { private final ReentrantLock lock = new ReentrantLock(); private long count = 0; public void increment() { lock.lock(); try { count++; } finally { lock.unlock(); } } public long getCount() { lock.lock(); try { return count; } finally { lock.unlock(); } } } LockCounter counter = new LockCounter(); long startTime = System.nanoTime(); CountDownLatch latch = new CountDownLatch(threadCount); for (int i = 0; i < threadCount; i++) { new Thread(() -> { for (int j = 0; j < operations; j++) { counter.increment(); } latch.countDown(); }).start(); } latch.await(); long endTime = System.nanoTime(); System.out.println("ReentrantLock - 耗时: " + (endTime - startTime) / 1_000_000 + "ms, 结果: " + counter.getCount()); } private static void testAtomicLong(int threadCount, int operations) throws InterruptedException { AtomicLong counter = new AtomicLong(0); long startTime = System.nanoTime(); CountDownLatch latch = new CountDownLatch(threadCount); for (int i = 0; i < threadCount; i++) { new Thread(() -> { for (int j = 0; j < operations; j++) { counter.incrementAndGet(); } latch.countDown(); }).start(); } latch.await(); long endTime = System.nanoTime(); System.out.println("AtomicLong - 耗时: " + (endTime - startTime) / 1_000_000 + "ms, 结果: " + counter.get()); } private static void testNoSync(int threadCount, int operations) throws InterruptedException { class UnsafeCounter { private long count = 0; public void increment() { count++; } public long getCount() { return count; } } UnsafeCounter counter = new UnsafeCounter(); long startTime = System.nanoTime(); CountDownLatch latch = new CountDownLatch(threadCount); for (int i = 0; i < threadCount; i++) { new Thread(() -> { for (int j = 0; j < operations; j++) { counter.increment(); } latch.countDown(); }).start(); } latch.await(); long endTime = System.nanoTime(); System.out.println("无同步(不安全) - 耗时: " + (endTime - startTime) / 1_000_000 + "ms, 结果: " + counter.getCount() + " (期望: " + (threadCount * operations) + ")"); } public static void threadPoolSizeOptimization() throws InterruptedException { System.out.println("\n=== 线程池大小优化 ==="); int[] poolSizes = {1, 2, 4, 8, 16, 32}; int taskCount = 100; for (int poolSize : poolSizes) { testThreadPoolPerformance(poolSize, taskCount); } } private static void testThreadPoolPerformance(int poolSize, int taskCount) throws InterruptedException { ExecutorService executor = Executors.newFixedThreadPool(poolSize); long startTime = System.nanoTime(); CountDownLatch latch = new CountDownLatch(taskCount); for (int i = 0; i < taskCount; i++) { executor.submit(() -> { try { long sum = 0; for (int j = 0; j < 1000000; j++) { sum += j; } Thread.sleep(10); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { latch.countDown(); } }); } latch.await(); long endTime = System.nanoTime(); executor.shutdown(); executor.awaitTermination(5, TimeUnit.SECONDS); System.out.println("线程池大小: " + poolSize + ", 耗时: " + (endTime - startTime) / 1_000_000 + "ms"); } public static void main(String[] args) throws InterruptedException { synchronizationPerformanceTest(); threadPoolSizeOptimization(); } }
|
并发编程最佳实践
1. 线程安全设计原则
- 不可变性优先:优先使用不可变对象,避免共享可变状态
- 最小化共享:减少线程间共享的数据,使用线程本地存储
- 正确使用同步:选择合适的同步机制,避免过度同步
- 避免死锁:统一锁顺序,使用超时机制,避免嵌套锁
2. 性能优化策略
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 36
| public class ThreadLocalExample { private static final ThreadLocal<SimpleDateFormat> dateFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); public static String formatDate(Date date) { return dateFormat.get().format(date); } }
public class SegmentedCounter { private final AtomicLong[] segments; private final int segmentCount; public SegmentedCounter(int segmentCount) { this.segmentCount = segmentCount; this.segments = new AtomicLong[segmentCount]; for (int i = 0; i < segmentCount; i++) { segments[i] = new AtomicLong(0); } } public void increment() { int segment = Thread.currentThread().hashCode() % segmentCount; segments[Math.abs(segment)].incrementAndGet(); } public long sum() { long total = 0; for (AtomicLong segment : segments) { total += segment.get(); } return total; } }
|
3. 异常处理和监控
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
| public class ThreadExceptionHandler implements Thread.UncaughtExceptionHandler { @Override public void uncaughtException(Thread t, Throwable e) { System.err.println("线程 " + t.getName() + " 发生未捕获异常: " + e.getMessage()); e.printStackTrace(); logException(t, e); if (shouldRestartThread(e)) { restartThread(t); } } private void logException(Thread t, Throwable e) { } private boolean shouldRestartThread(Throwable e) { return !(e instanceof InterruptedException); } private void restartThread(Thread t) { } }
|
常见并发问题及解决方案
1. 死锁问题
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 36 37 38 39 40 41 42 43
| public class DeadlockPrevention { private static final Object lock1 = new Object(); private static final Object lock2 = new Object(); public static void transferMoney(Account from, Account to, double amount) { Account firstLock = from.getId() < to.getId() ? from : to; Account secondLock = from.getId() < to.getId() ? to : from; synchronized (firstLock) { synchronized (secondLock) { from.withdraw(amount); to.deposit(amount); } } } public static boolean tryTransferWithTimeout(Account from, Account to, double amount, long timeout, TimeUnit unit) throws InterruptedException { long deadline = System.nanoTime() + unit.toNanos(timeout); if (from.getLock().tryLock(timeout, unit)) { try { long remaining = deadline - System.nanoTime(); if (to.getLock().tryLock(remaining, TimeUnit.NANOSECONDS)) { try { from.withdraw(amount); to.deposit(amount); return true; } finally { to.getLock().unlock(); } } } finally { from.getLock().unlock(); } } return false; } }
|
2. 内存可见性问题
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
| public class VisibilityExample { private volatile boolean running = true; private volatile int counter = 0; public void stop() { running = false; } public void run() { while (running) { counter++; } } private final Object lock = new Object(); private boolean flag = false; public void setFlag(boolean value) { synchronized (lock) { flag = value; } } public boolean getFlag() { synchronized (lock) { return flag; } } }
|
总结
Java并发编程是一个复杂而重要的主题,需要深入理解其底层原理和实践技巧:
- 基础概念掌握:理解线程、进程、同步、异步等基本概念
- 同步机制选择:根据场景选择合适的同步工具(synchronized、Lock、原子类等)
- 线程池使用:合理配置线程池参数,避免资源浪费和性能问题
- 并发工具应用:熟练使用CountDownLatch、CyclicBarrier、Semaphore等工具
- 性能优化:通过性能测试找出瓶颈,采用合适的优化策略
- 问题排查:掌握常见并发问题的识别和解决方法
在实际开发中,应该遵循”先保证正确性,再优化性能”的原则,编写安全、高效的并发代码。同时要注意监控和日志记录,及时发现和解决并发问题。
通过本文的学习和实践,相信你已经对Java并发编程有了更深入的理解。继续实践和探索,你将能够在复杂的并发场景中游刃有余。
```