2026/2/21 19:12:22
网站建设
项目流程
如何做公司的英文网站,原创wordpress付费主题,php cms系统,建立个人网站的目的引言#xff1a;为什么需要多线程#xff1f;在当今多核处理器普及的时代#xff0c;充分利用计算资源已成为提升程序性能的关键。Java多线程允许程序同时执行多个任务#xff0c;显著提高应用程序的响应速度和处理能力。无论是Web服务器处理并发请求#xff0c;还是大数据…引言为什么需要多线程在当今多核处理器普及的时代充分利用计算资源已成为提升程序性能的关键。Java多线程允许程序同时执行多个任务显著提高应用程序的响应速度和处理能力。无论是Web服务器处理并发请求还是大数据处理中的并行计算多线程技术都扮演着重要角色。一、线程基础概念1.1 进程与线程的区别// 简单比喻进程是工厂线程是工厂中的流水线 public class ProcessVsThread { public static void main(String[] args) { // 进程拥有独立的内存空间 // 线程共享进程的内存空间轻量级执行单元 System.out.println(进程 - 独立内存空间重量级); System.out.println(线程 - 共享内存空间轻量级); } }1.2 Java线程的生命周期新建(New) → 就绪(Runnable) → 运行(Running) → 阻塞(Blocked) ↓ ↑ └────── 等待(Waiting) ←──────┘ ↓ 超时等待(Timed Waiting) ↓ 终止(Terminated)二、创建线程的三种方式2.1 继承Thread类不推荐只能继承一个类public class MyThread extends Thread { Override public void run() { System.out.println(线程执行: Thread.currentThread().getName()); } public static void main(String[] args) { MyThread thread1 new MyThread(); MyThread thread2 new MyThread(); thread1.start(); // 启动线程 thread2.start(); } }2.2 实现Runnable接口推荐可以有多个接口也能继承类public class MyRunnable implements Runnable { Override public void run() { for (int i 0; i 5; i) { System.out.println(Thread.currentThread().getName() : i); try { Thread.sleep(500); // 模拟耗时操作 } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) { Thread thread1 new Thread(new MyRunnable(), 线程A); Thread thread2 new Thread(new MyRunnable(), 线程B); thread1.start(); thread2.start(); } }2.3 实现Callable接口带返回值import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; public class MyCallable implements CallableInteger { private final int number; public MyCallable(int number) { this.number number; } Override public Integer call() throws Exception { System.out.println(计算中... Thread.currentThread().getName()); Thread.sleep(1000); return number * number; // 返回计算结果 } public static void main(String[] args) throws Exception { FutureTaskInteger futureTask new FutureTask(new MyCallable(5)); Thread thread new Thread(futureTask, 计算线程); thread.start(); // 获取计算结果会阻塞直到计算完成 Integer result futureTask.get(); System.out.println(计算结果: result); } }三、线程同步与线程安全3.1 同步问题示例银行取款public class BankAccount { private double balance; public BankAccount(double initialBalance) { this.balance initialBalance; } // 线程不安全的方法 public void unsafeWithdraw(double amount) { if (balance amount) { try { Thread.sleep(100); // 模拟处理时间 } catch (InterruptedException e) { e.printStackTrace(); } balance - amount; System.out.println(Thread.currentThread().getName() 取款 amount 余额: balance); } } // 使用synchronized保证线程安全 public synchronized void safeWithdraw(double amount) { if (balance amount) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } balance - amount; System.out.println(Thread.currentThread().getName() 取款 amount 余额: balance); } } }3.2 同步方法对比public class SynchronizationDemo { private int counter 0; // 1. 同步实例方法 public synchronized void incrementSyncMethod() { counter; } // 2. 同步代码块 public void incrementSyncBlock() { synchronized(this) { counter; } } // 3. 同步静态方法 public static synchronized void staticSyncMethod() { // 类级别的锁 } // 4. 使用Lock对象更灵活 private final Lock lock new ReentrantLock(); public void incrementWithLock() { lock.lock(); try { counter; } finally { lock.unlock(); // 确保锁被释放 } } }3.3 volatile关键字public class VolatileDemo { // volatile保证可见性不保证原子性 private volatile boolean flag true; public void stop() { flag false; } public void work() { while (flag) { // 工作逻辑 } System.out.println(线程停止); } }四、线程间通信4.1 wait() 和 notify() 机制public class ProducerConsumerExample { private final ListInteger buffer new LinkedList(); private final int CAPACITY 5; public void produce() throws InterruptedException { int value 0; while (true) { synchronized (this) { // 缓冲区满时等待 while (buffer.size() CAPACITY) { wait(); } System.out.println(生产: value); buffer.add(value); // 通知消费者 notify(); Thread.sleep(1000); } } } public void consume() throws InterruptedException { while (true) { synchronized (this) { // 缓冲区空时等待 while (buffer.isEmpty()) { wait(); } int value buffer.remove(0); System.out.println(消费: value); // 通知生产者 notify(); Thread.sleep(1000); } } } }五、线程池Thread Pool5.1 Executors工具类import java.util.concurrent.*; public class ThreadPoolDemo { public static void main(String[] args) { // 1. 固定大小线程池 ExecutorService fixedPool Executors.newFixedThreadPool(5); // 2. 单线程线程池 ExecutorService singleThreadPool Executors.newSingleThreadExecutor(); // 3. 缓存线程池 ExecutorService cachedPool Executors.newCachedThreadPool(); // 4. 定时任务线程池 ScheduledExecutorService scheduledPool Executors.newScheduledThreadPool(3); // 提交任务 for (int i 0; i 10; i) { final int taskId i; fixedPool.execute(() - { System.out.println(执行任务 taskId 线程: Thread.currentThread().getName()); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } }); } // 优雅关闭线程池 fixedPool.shutdown(); try { if (!fixedPool.awaitTermination(60, TimeUnit.SECONDS)) { fixedPool.shutdownNow(); } } catch (InterruptedException e) { fixedPool.shutdownNow(); } } }5.2 自定义线程池public class CustomThreadPool { public static void main(String[] args) { ThreadPoolExecutor executor new ThreadPoolExecutor( 2, // 核心线程数 5, // 最大线程数 60L, // 空闲线程存活时间 TimeUnit.SECONDS, new ArrayBlockingQueue(10), // 任务队列 Executors.defaultThreadFactory(), // 线程工厂 new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略 ); // 监控线程池状态 ScheduledExecutorService monitor Executors.newScheduledThreadPool(1); monitor.scheduleAtFixedRate(() - { System.out.println(活跃线程数: executor.getActiveCount()); System.out.println(队列大小: executor.getQueue().size()); System.out.println(完成任务数: executor.getCompletedTaskCount()); }, 0, 1, TimeUnit.SECONDS); } }六、高级并发工具类6.1 CountDownLatch倒计时门闩public class CountDownLatchDemo { public static void main(String[] args) throws InterruptedException { int workerCount 5; CountDownLatch startLatch new CountDownLatch(1); CountDownLatch endLatch new CountDownLatch(workerCount); for (int i 0; i workerCount; i) { new Thread(() - { try { startLatch.await(); // 等待开始信号 System.out.println(Thread.currentThread().getName() 开始工作); Thread.sleep((long) (Math.random() * 1000)); System.out.println(Thread.currentThread().getName() 完成工作); endLatch.countDown(); // 任务完成 } catch (InterruptedException e) { e.printStackTrace(); } }).start(); } System.out.println(准备开始所有工作...); Thread.sleep(1000); startLatch.countDown(); // 发出开始信号 endLatch.await(); // 等待所有任务完成 System.out.println(所有工作完成); } }6.2 CyclicBarrier循环屏障public class CyclicBarrierDemo { public static void main(String[] args) { int threadCount 3; CyclicBarrier barrier new CyclicBarrier(threadCount, () - System.out.println(所有线程到达屏障继续执行)); for (int i 0; i threadCount; i) { final int threadId i; new Thread(() - { try { System.out.println(线程 threadId 准备阶段1); Thread.sleep(1000); barrier.await(); System.out.println(线程 threadId 准备阶段2); Thread.sleep(1000); barrier.await(); System.out.println(线程 threadId 完成); } catch (Exception e) { e.printStackTrace(); } }).start(); } } }6.3 Semaphore信号量public class SemaphoreDemo { public static void main(String[] args) { // 模拟3个停车位 Semaphore semaphore new Semaphore(3); // 10辆车需要停车 for (int i 1; i 10; i) { final int carId i; new Thread(() - { try { System.out.println(车辆 carId 等待停车); semaphore.acquire(); System.out.println(车辆 carId 停车成功); Thread.sleep(2000); // 停车时间 System.out.println(车辆 carId 离开); semaphore.release(); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); } } }七、并发集合7.1 常用并发集合类public class ConcurrentCollections { public static void main(String[] args) { // 1. ConcurrentHashMap线程安全的HashMap ConcurrentHashMapString, Integer concurrentMap new ConcurrentHashMap(); concurrentMap.put(key1, 1); concurrentMap.putIfAbsent(key1, 2); // 不存在时才添加 // 2. CopyOnWriteArrayList读多写少的场景 CopyOnWriteArrayListString copyOnWriteList new CopyOnWriteArrayList(); copyOnWriteList.add(item1); copyOnWriteList.addIfAbsent(item1); // 线程安全的添加 // 3. ConcurrentLinkedQueue无界线程安全队列 ConcurrentLinkedQueueString concurrentQueue new ConcurrentLinkedQueue(); concurrentQueue.offer(task1); String task concurrentQueue.poll(); // 4. BlockingQueue阻塞队列 BlockingQueueString blockingQueue new ArrayBlockingQueue(10); try { blockingQueue.put(element); // 阻塞直到有空间 String element blockingQueue.take(); // 阻塞直到有元素 } catch (InterruptedException e) { e.printStackTrace(); } } }八、最佳实践与常见问题8.1 多线程最佳实践public class BestPractices { // 1. 使用线程池而不是直接创建线程 private final ExecutorService executor Executors.newFixedThreadPool( Runtime.getRuntime().availableProcessors() ); // 2. 使用局部变量避免共享状态 public void process() { String localVariable 安全; // 线程安全 // ... } // 3. 使用不可变对象 public final class ImmutablePerson { private final String name; private final int age; public ImmutablePerson(String name, int age) { this.name name; this.age age; } // 只有getter没有setter } // 4. 避免死锁 public void avoidDeadlock() { // 按固定顺序获取锁 Object lock1 new Object(); Object lock2 new Object(); Thread thread1 new Thread(() - { synchronized (lock1) { try { Thread.sleep(100); } catch (InterruptedException e) {} synchronized (lock2) { // 操作 } } }); Thread thread2 new Thread(() - { synchronized (lock1) { // 与thread1相同的顺序 try { Thread.sleep(100); } catch (InterruptedException e) {} synchronized (lock2) { // 操作 } } }); } }8.2 常见问题与调试public class ThreadDebugging { // 1. 线程死锁检测 public static void detectDeadlock() { ThreadMXBean threadMXBean ManagementFactory.getThreadMXBean(); long[] threadIds threadMXBean.findDeadlockedThreads(); if (threadIds ! null) { ThreadInfo[] threadInfos threadMXBean.getThreadInfo(threadIds); for (ThreadInfo threadInfo : threadInfos) { System.out.println(死锁线程: threadInfo.getThreadName()); } } } // 2. 线程堆栈分析 public static void printAllStackTraces() { MapThread, StackTraceElement[] allStackTraces Thread.getAllStackTraces(); for (Map.EntryThread, StackTraceElement[] entry : allStackTraces.entrySet()) { Thread thread entry.getKey(); System.out.println(\n线程: thread.getName() - 状态: thread.getState()); for (StackTraceElement element : entry.getValue()) { System.out.println( element); } } } // 3. 使用ThreadLocal private static final ThreadLocalSimpleDateFormat dateFormatter ThreadLocal.withInitial(() - new SimpleDateFormat(yyyy-MM-dd)); public static String formatDate(Date date) { return dateFormatter.get().format(date); } }九、CompletableFutureJava 8public class CompletableFutureDemo { public static void main(String[] args) throws Exception { // 1. 创建异步任务 CompletableFutureString future1 CompletableFuture.supplyAsync(() - { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } return 结果1; }); CompletableFutureString future2 CompletableFuture.supplyAsync(() - { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } return 结果2; }); // 2. 组合多个Future CompletableFutureString combined future1.thenCombine(future2, (result1, result2) - result1 result2); // 3. 异步回调 combined.thenAccept(result - { System.out.println(最终结果: result); }); // 4. 异常处理 CompletableFuture.supplyAsync(() - { if (Math.random() 0.5) { throw new RuntimeException(模拟异常); } return 成功; }).exceptionally(ex - { System.out.println(处理异常: ex.getMessage()); return 默认值; }); // 等待所有任务完成 CompletableFuture.allOf(future1, future2).join(); } }十、实战案例并发下载器public class ConcurrentDownloader { private final ExecutorService executor; private final int maxConcurrentDownloads; public ConcurrentDownloader(int maxConcurrentDownloads) { this.maxConcurrentDownloads maxConcurrentDownloads; this.executor Executors.newFixedThreadPool(maxConcurrentDownloads); } public void downloadFiles(ListString urls) { CountDownLatch latch new CountDownLatch(urls.size()); ListFutureFile futures new ArrayList(); for (String url : urls) { CallableFile downloadTask () - { try { System.out.println(开始下载: url); // 模拟下载过程 Thread.sleep((long) (Math.random() * 3000)); System.out.println(下载完成: url); return new File(url.substring(url.lastIndexOf(/) 1)); } finally { latch.countDown(); } }; futures.add(executor.submit(downloadTask)); } try { // 等待所有下载完成 latch.await(); System.out.println(所有文件下载完成); // 处理下载结果 for (FutureFile future : futures) { try { File file future.get(); // 处理文件 } catch (ExecutionException e) { System.err.println(下载失败: e.getCause()); } } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } public void shutdown() { executor.shutdown(); try { if (!executor.awaitTermination(60, TimeUnit.SECONDS)) { executor.shutdownNow(); } } catch (InterruptedException e) { executor.shutdownNow(); } } }结语Java多线程编程是一个强大但需要谨慎使用的工具。掌握多线程技术需要理解基础概念线程生命周期、同步机制高级特性线程池、并发工具类最佳实践避免死锁、减少锁竞争调试技巧分析线程转储、监控线程状态在实际开发中建议优先使用高层并发工具如Executor框架尽量使用不可变对象和线程安全集合合理设置线程池参数编写可测试的并发代码记住始终将线程安全放在首位。