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}