Java 多线程
多线程是 Java 编程中的重要概念,它允许程序同时执行多个任务,从而提高程序的效率和响应速度。通过本文的学习,你将掌握线程的基本概念、创建线程的几种方式、线程的生命周期以及线程的状态管理。
1. 什么是线程?
进程是计算机中已运行的程序,它是一个动态执行的过程。例如,同时运行的浏览器、QQ 和代码编辑器就是三个不同的进程。
线程是操作系统能够进行运算调度的最小单位。一个进程可以包含多个线程,线程是进程中的实际运作单位,因此也被称为轻量级进程。
总结:
- 进程:程序的执行实例。
- 线程:进程中的执行单元,多个线程可以共享进程的资源。
2. 创建线程的三种方式
在 Java 中,创建线程有以下三种方式:
- 继承
Thread
类。 - 实现
Runnable
接口。 - 实现
Callable
接口。
2.1 继承 Thread
类
通过继承 Thread
类并重写 run()
方法来创建线程。
步骤:
- 定义
Thread
类的子类,并重写run()
方法。 - 创建子类的实例。
- 调用
start()
方法启动线程。
示例:
public class ThreadDemo1 extends Thread {
@Override
public void run() {
System.out.println("这里是线程体");
System.out.println(getName()); // 打印线程名称
}
public static void main(String[] args) {
ThreadDemo1 thread = new ThreadDemo1();
thread.start(); // 启动线程
}
}
输出:
这里是线程体
Thread-0
2.2 实现 Runnable
接口
通过实现 Runnable
接口并实现 run()
方法来创建线程。
步骤:
- 定义
Runnable
接口的实现类,并实现run()
方法。 - 创建实现类的实例。
- 将实例作为参数传递给
Thread
类的构造函数,创建线程对象。 - 调用
start()
方法启动线程。
示例:
public class RunnableDemo1 implements Runnable {
private int i = 5;
@Override
public void run() {
while (i > 0) {
System.out.println(Thread.currentThread().getName() + " i = " + i);
i--;
}
}
public static void main(String[] args) {
RunnableDemo1 runnable = new RunnableDemo1();
Thread thread1 = new Thread(runnable, "线程1");
Thread thread2 = new Thread(runnable, "线程2");
thread1.start();
thread2.start();
}
}
输出:
线程1 i = 5
线程1 i = 4
线程2 i = 5
线程1 i = 3
线程2 i = 4
线程1 i = 2
线程2 i = 3
线程1 i = 1
线程2 i = 2
线程2 i = 1
2.3 实现 Callable
接口
通过实现 Callable
接口并实现 call()
方法来创建线程。Callable
接口允许线程返回结果。
步骤:
- 定义
Callable
接口的实现类,并实现call()
方法。 - 创建实现类的实例。
- 使用
FutureTask
类包装Callable
对象。 - 将
FutureTask
对象作为参数传递给Thread
类的构造函数,创建线程对象。 - 调用
start()
方法启动线程。 - 调用
FutureTask
对象的get()
方法获取线程执行结果。
示例:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class CallableDemo1 {
static class MyThread implements Callable<String> {
@Override
public String call() {
return "我是线程中返回的字符串";
}
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
Callable<String> callable = new MyThread();
FutureTask<String> futureTask = new FutureTask<>(callable);
Thread thread = new Thread(futureTask);
thread.start();
String result = futureTask.get();
System.out.println(result);
}
}
输出:
我是线程中返回的字符串
3. 线程休眠
通过 Thread.sleep()
方法可以使当前线程休眠指定的毫秒数。
示例:
public class SleepDemo implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println(Thread.currentThread().getName() + ":执行第" + i + "次");
try {
Thread.sleep(1000); // 休眠1秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
SleepDemo sleepDemo = new SleepDemo();
Thread thread = new Thread(sleepDemo);
thread.start();
}
}
输出:
Thread-0:执行第1次
Thread-0:执行第2次
Thread-0:执行第3次
Thread-0:执行第4次
Thread-0:执行第5次
4. 线程的状态和生命周期
Java 中的线程有以下六种状态:
- NEW:新建状态,线程尚未启动。
- RUNNABLE:可运行状态,线程正在执行或等待 CPU 资源。
- BLOCKED:阻塞状态,线程等待监视器锁。
- WAITING:等待状态,线程无限期等待其他线程执行特定操作。
- TIMED_WAITING:定时等待状态,线程在指定时间内等待。
- TERMINATED:终止状态,线程执行完毕。
线程生命周期:
- 线程从
NEW
状态开始,调用start()
方法后进入RUNNABLE
状态。 - 根据线程的执行情况,可能会进入
BLOCKED
、WAITING
或TIMED_WAITING
状态。 - 最终,线程进入
TERMINATED
状态。
5. 总结
- 线程的创建:可以通过继承
Thread
类、实现Runnable
接口或实现Callable
接口来创建线程。 - 线程休眠:使用
Thread.sleep()
方法使线程休眠。 - 线程状态:线程有六种状态,分别是
NEW
、RUNNABLE
、BLOCKED
、WAITING
、TIMED_WAITING
和TERMINATED
。