📌 目录
- Java 多线程编程简介
- Java 创建线程的方式
- 2.1 继承
Thread
类 - 2.2 实现
Runnable
接口 - 2.3 使用
ExecutorService
- 2.1 继承
- 线程生命周期
- 线程同步
- 4.1 使用
synchronized
关键字 - 4.2 使用
ReentrantLock
- 4.1 使用
- 线程间通信
- 线程池
- 常见的多线程类
- 总结
- 参考资料
- 出站链接
1. Java 多线程编程简介
多线程是指在同一个程序中,可以同时运行多个线程。每个线程都有自己的执行路径,但它们共享程序的资源。多线程的使用可以提高程序的效率,特别是在需要处理大量计算或等待外部资源的情况下。Java 提供了多种方式来实现多线程编程,包括继承 Thread
类、实现 Runnable
接口以及使用线程池等。
2. Java 创建线程的方式
2.1 继承 Thread
类
一种创建线程的方法是通过继承 Thread
类并重写其 run()
方法。
class MyThread extends Thread {
@Override
public void run() {
System.out.println("Thread is running");
}
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start(); // 启动线程
}
}
在这个例子中,MyThread
类继承了 Thread
类,并重写了 run()
方法。通过调用 start()
方法来启动线程。
2.2 实现 Runnable
接口
另一种创建线程的方法是实现 Runnable
接口并将其传递给 Thread
类的构造函数。
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Runnable thread is running");
}
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
thread.start(); // 启动线程
}
}
通过实现 Runnable
接口,我们可以将任务与线程分开,允许多个线程共享同一个任务。Runnable
更适用于任务的重用。
2.3 使用 ExecutorService
ExecutorService
提供了一种更为高级和灵活的方式来管理线程池,推荐用于大多数场景。通过 ExecutorService
,我们可以有效地管理线程池中的线程,并提供任务的执行和管理。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Executor service thread is running");
}
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(10); // 创建一个线程池
executor.submit(new MyRunnable()); // 提交任务
executor.shutdown(); // 关闭线程池
}
}
ExecutorService
通过 submit()
提交任务,并且支持更灵活的线程管理,如线程池大小的设置、任务的提交等。
3. 线程生命周期
线程的生命周期可以分为以下几个状态:
- 新建状态 (
New
):线程被创建但尚未启动。 - 可运行状态 (
Runnable
):线程已经启动,正在等待 CPU 时间片的分配。 - 阻塞状态 (
Blocked
):线程等待资源(如 I/O 操作、锁)释放。 - 等待状态 (
Waiting
):线程等待其他线程的某些条件发生。 - 超时等待状态 (
Timed Waiting
):线程等待一段时间。 - 终止状态 (
Terminated
):线程执行完毕或因异常终止。
4. 线程同步
在多线程环境中,多个线程可能会共享同一资源,因此需要保证对共享资源的访问是互斥的。Java 提供了几种方式来实现线程同步。
4.1 使用 synchronized
关键字
synchronized
关键字可以用来修饰方法或代码块,确保同一时刻只有一个线程能够访问共享资源。
class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
}
通过在方法上添加 synchronized
关键字,我们确保了多个线程对 increment()
和 getCount()
方法的访问是互斥的。
4.2 使用 ReentrantLock
ReentrantLock
提供了比 synchronized
更灵活的锁机制,支持超时、可中断等高级特性。
import java.util.concurrent.locks.ReentrantLock;
class Counter {
private int count = 0;
private final ReentrantLock lock = new ReentrantLock();
public void increment() {
lock.lock(); // 获取锁
try {
count++;
} finally {
lock.unlock(); // 释放锁
}
}
public int getCount() {
return count;
}
}
ReentrantLock
允许更精细的控制,例如尝试加锁或设置加锁的超时时间。
5. 线程间通信
线程间通信是指线程之间相互协调,以实现任务的同步和数据的共享。常见的线程间通信方法包括 wait()
、notify()
和 notifyAll()
。
class SharedResource {
private int count = 0;
public synchronized void increment() {
count++;
notify(); // 通知等待的线程
}
public synchronized void waitForCondition() throws InterruptedException {
while (count == 0) {
wait(); // 等待其他线程的通知
}
}
}
在这个例子中,waitForCondition()
方法会在 count
为 0 时让线程进入等待状态,直到其他线程调用 notify()
方法唤醒它。
6. 线程池
线程池是一种资源管理机制,它通过重复使用线程来减少频繁创建和销毁线程的开销。Java 提供了 ExecutorService
接口以及几个实现类来管理线程池。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(5); // 创建大小为 5 的线程池
for (int i = 0; i < 10; i++) {
executor.submit(() -> {
System.out.println(Thread.currentThread().getName() + " is running");
});
}
executor.shutdown(); // 关闭线程池
}
}
线程池通过 Executors
类提供了多种方式创建不同类型的线程池,如固定大小的线程池 (newFixedThreadPool
)、单个线程池 (newSingleThreadExecutor
) 和可缓存的线程池 (newCachedThreadPool
)。
7. 常见的多线程类
- Thread: Java 提供的基本线程类。
- Runnable: 定义线程任务的接口,通常与
Thread
配合使用。 - ExecutorService: 提供更高级的线程池管理。
- ReentrantLock: 提供更灵活的锁控制机制。
- CountDownLatch: 用于控制多个线程等待某个事件的发生。
- CyclicBarrier: 使一组线程互相等待直到达到某个公共屏障点。
- Semaphore: 控制对某些资源的访问数目。
8. 总结
Java 多线程编程是一个非常强大的工具,能够使程序在需要时执行并行处理。通过合理使用线程池、同步机制、线程间通信等技术,可以有效提高程序的性能和可靠性。然而,线程编程也带来了许多挑战,如死锁、资源竞争等问题,需要谨慎设计和管理。
发表回复