从零开始写多线程
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 | 1. Java 多线程的基本概念 1.1 线程与进程 进程:是操作系统分配资源的基本单位,每个进程都有独立的内存空间。 线程:是进程内的一个执行单元,同一进程中的线程共享进程的内存空间,线程间的通信更为高效。 1.2 线程的好处 提高系统响应性:可以实现用户界面与后台处理的并发执行,使得程序即使在处理耗时操作时也能保持响应。 提高性能:充分利用多核处理器的能力,同时处理多个任务。 2. 创建线程的两种方式 2.1 继承 Thread 类 可以通过继承 Thread 类并重写 run() 方法来创建线程。 1class MyThread extends Thread { 2 @Override 3 public void run() { 4 System. out .println( "Thread running..." ); 5 } 6 7 public static void main(String[] args) { 8 MyThread thread = new MyThread(); 9 thread.start(); // 启动线程 10 } 11} 2.2 实现 Runnable 接口 也可以实现 Runnable 接口,并将其实例作为参数传递给 Thread 的构造函数。 1class MyRunnable implements Runnable { 2 @Override 3 public void run() { 4 System. out .println( "Runnable running..." ); 5 } 6 7 public static void main(String[] args) { 8 Thread thread = new Thread( new MyRunnable()); 9 thread.start(); 10 } 11} 3. 线程的生命周期 线程的生命周期包括以下几个阶段: 新建 (NEW):当一个线程对象被创建但尚未启动时。 就绪 (RUNNABLE):线程被启动后,等待 CPU 时间片。 运行 (RUNNABLE):线程获得了 CPU 时间片并开始执行。 阻塞 (BLOCKED):线程因等待某种条件(如 I/O 操作或同步锁)而暂时停止运行。 等待/休眠 (WAITING):线程因等待特定事件的发生(如 wait() 方法)而暂停运行。 定时等待 (TIMED_WAITING):线程因等待一定时间(如 sleep() 方法)而暂停运行。 终止 (TERMINATED):线程执行完毕或被异常终止。 4. 线程同步 4.1 同步锁 为了保证多线程环境下对共享资源的正确访问,可以使用同步锁(Synchronized)来保护临界区。 1public class Counter { 2 private int count = 0; 3 4 public synchronized void increment() { 5 count++; 6 } 7 8 public synchronized int getCount() { 9 return count; 10 } 11} 4.2 volatile 关键字 volatile 关键字可以用来标记一个变量是共享的,确保了对变量的可见性和禁止指令重排。 1public class Counter { 2 private volatile int count = 0; 3 4 public void increment() { 5 count++; 6 } 7 8 public int getCount() { 9 return count; 10 } 11} 4.3 Lock 接口 Lock 接口提供了更灵活的锁定机制,可以实现更复杂的同步策略。 1import java.util.concurrent.locks.Lock; 2import java.util.concurrent.locks.ReentrantLock; 3 4public class Counter { 5 private int count = 0; 6 private final Lock lock = new ReentrantLock(); 7 8 public void increment() { 9 lock . lock (); 10 try { 11 count++; 12 } finally { 13 lock .unlock(); 14 } 15 } 16 17 public int getCount() { 18 return count; 19 } 20} 5. 线程间通信 5.1 wait() 和 notify() wait() 和 notify() 方法可以用来实现线程间的通信。 1public class Counter { 2 private int count = 0; 3 private final Object monitor = new Object(); 4 5 public void increment() { 6 synchronized (monitor) { 7 count++; 8 monitor.notify(); 9 } 10 } 11 12 public void decrement() { 13 synchronized (monitor) { 14 while (count == 0) { 15 try { 16 monitor.wait(); 17 } catch (InterruptedException e) { 18 e.printStackTrace(); 19 } 20 } 21 count--; 22 } 23 } 24} 5.2 生产者-消费者模式 生产者-消费者模式是一种经典的线程协作模型,通过队列来实现生产者和消费者之间的解耦。 1import java.util.concurrent.BlockingQueue; 2import java.util.concurrent.LinkedBlockingQueue; 3 4public class ProducerConsumerDemo { 5 private static final BlockingQueue<Integer> queue = new LinkedBlockingQueue<>(10); 6 7 public static void main(String[] args) { 8 Thread producer = new Thread(() -> { 9 try { 10 for ( int i = 0; i < 100; i++) { 11 queue.put(i); 12 System. out .println( "Produced: " + i); 13 } 14 } catch (InterruptedException e) { 15 e.printStackTrace(); 16 } 17 }); 18 19 Thread consumer = new Thread(() -> { 20 try { 21 for ( int i = 0; i < 100; i++) { 22 int item = queue.take(); 23 System. out .println( "Consumed: " + item); 24 } 25 } catch (InterruptedException e) { 26 e.printStackTrace(); 27 } 28 }); 29 30 producer.start(); 31 consumer.start(); 32 } 33} 6. 线程池 线程池可以有效地管理线程,避免频繁创建和销毁线程所带来的开销。 1import java.util.concurrent.ExecutorService; 2import java.util.concurrent.Executors; 3 4public class ThreadPoolDemo { 5 public static void main(String[] args) { 6 ExecutorService executor = Executors.newFixedThreadPool(5); 7 8 for ( int i = 0; i < 10; i++) { 9 executor.submit(() -> { 10 System. out .println(Thread.currentThread().getName() + " is running" ); 11 }); 12 } 13 14 executor.shutdown(); 15 } 16} 7. 线程中断 线程中断是一种通知线程终止的方式。 1public class ThreadInterruptDemo { 2 public static void main(String[] args) throws InterruptedException { 3 Thread thread = new Thread(() -> { 4 try { 5 while (!Thread.currentThread().isInterrupted()) { 6 Thread.sleep(1000); 7 System. out .println( "Running..." ); 8 } 9 } catch (InterruptedException e) { 10 System. out .println( "Interrupted!" ); 11 Thread.currentThread().interrupt(); // 重置中断标志 12 } 13 }); 14 15 thread.start(); 16 Thread.sleep(5000); 17 thread.interrupt(); 18 } 19} 8. 线程安全的容器 Java 提供了一些线程安全的容器类,如 Vector、ConcurrentHashMap 等。 1import java.util.concurrent.ConcurrentHashMap; 2 3public class ThreadSafeContainerDemo { 4 private static ConcurrentHashMap<Integer, String> map = new ConcurrentHashMap<>(); 5 6 public static void main(String[] args) { 7 Thread t1 = new Thread(() -> { 8 for ( int i = 0; i < 100; i++) { 9 map.put(i, "Value " + i); 10 } 11 }); 12 13 Thread t2 = new Thread(() -> { 14 for ( int i = 0; i < 100; i++) { 15 map.remove(i); 16 } 17 }); 18 19 t1.start(); 20 t2.start(); 21 } 22} |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了