Java作为一门广泛应用的编程语言,其强大的多线程支持是许多开发者选择它的重要原因之一。多线程编程不仅可以提高程序的效率,还能改善用户体验。但同时,多线程编程也引入了一系列复杂的问题,如线程安全、死锁等。本文将从基础到实践,全面解析Java中的多线程编程。
一、线程的创建与管理
在Java中,创建线程有两种常见的方式:继承Thread类和实现Runnable接口。Thread类的方法start()用于启动一个新线程,而run()方法包含线程执行的代码。实现Runnable接口则更符合面向对象的设计原则,因为它允许你的类继承其他类。
// 继承Thread类
class MyThread extends Thread {
public void run() {
System.out.println("MyThread is running");
}
}
// 实现Runnable接口
class MyRunnable implements Runnable {
public void run() {
System.out.println("MyRunnable is running");
}
}
二、线程的生命周期
线程从创建到终止经历了新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)、死亡(Terminated)几个状态。理解这些状态有助于合理控制线程行为。
三、线程同步
在多线程环境中,多个线程可能会同时访问共享资源,导致数据不一致。Java提供了多种同步机制来保证线程安全,包括synchronized关键字和重入锁(ReentrantLock)。
// 使用synchronized关键字
class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
}
// 使用ReentrantLock
import java.util.concurrent.locks.ReentrantLock;
class CounterWithLock {
private final ReentrantLock lock = new ReentrantLock();
private int count = 0;
public void increment() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
}
四、线程间通信
有时候,一个线程需要等待另一个线程完成某些操作后再继续执行。Java提供了Object类的wait()、notify()和notifyAll()方法来实现线程间的通信。
```java
class CommunicationDemo {
public static void main(String[] args) throws InterruptedException {
final Object lock = new Object();
Thread t1 = new Thread(() -> {
synchronized (lock) {
try {
System.out.println("Thread 1 is waiting");
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread 1 is resumed");
}
});
Thread t2 = new Thread(() -> {
synchronized (lock) {
System.out.println("Thread 2 is notifying");
lock.notify();
}
});
t1.start();
Thread.