多线程编程是现代软件开发中不可或缺的一部分,它允许程序同时执行多个任务,大大提高应用程序的效率和响应能力。
一,创建线程的两种方式
1. 继承Thread类
public class MyThread extends Thread {
@Override
public void run() {
// 线程执行的代码
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + ": " + i);
try {
Thread.sleep(500); // 线程休眠500毫秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
使用方法
public class Main {
public static void main(String[] args) {
MyThread thread1 = new MyThread();
MyThread thread2 = new MyThread();
thread1.start(); // 启动线程1
thread2.start(); // 启动线程2
}
}
2. 实现Runnable接口
public class MyRunnable implements Runnable {
@Override
public void run() {
// 线程执行的代码
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + ": " + i);
try {
Thread.sleep(500); // 线程休眠500毫秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
使用方法
public class Main {
public static void main(String[] args) {
Thread thread1 = new Thread(new MyRunnable());
Thread thread2 = new Thread(new MyRunnable());
thread1.start(); // 启动线程1
thread2.start(); // 启动线程2
}
}
推荐使用实现Runnable接口的方式:
- Java不支持多重继承,实现接口更灵活
- 代码和线程控制分离,更符合面向对象设计原则
- 适合多个线程处理同一资源的情况
二,线程的常用方法
1. start() - 启动线程
调用`start()`方法会启动新线程并执行`run()`方法。注意:不要直接调用`run()`方法,否则它会在当前线程中执行,而不是新线程。
Thread thread = new Thread(new MyRunnable());
thread.start(); // 正确方式
// thread.run(); // 错误方式 - 不会启动新线程
2. sleep() - 线程休眠
让当前线程暂停执行指定的时间(毫秒),但不会释放锁。(关于锁我会在后续博客中进行讲解)
try {
Thread.sleep(1000); // 休眠1秒
} catch (InterruptedException e) {
e.printStackTrace();
}
需要设置在指定的线程方法中,更能精准的操控线程的运行
3. join() - 等待线程结束
等待调用该方法的线程执行完毕,当前线程才会继续执行。
Thread thread = new Thread(new MyRunnable());
thread.start();
try {
thread.join(); // 等待thread线程执行完毕
System.out.println("thread线程已执行完毕");
} catch (InterruptedException e) {
e.printStackTrace();
}
4. interrupt() - 中断线程
向线程发送中断信号,但线程是否中断取决于其实现。
Thread thread = new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
// 检查中断状态
System.out.println("线程运行中...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// 捕获中断异常后,中断状态会被清除
System.out.println("线程被中断");
Thread.currentThread().interrupt(); // 重新设置中断状态
}
}
System.out.println("线程结束");
});
thread.start();
// 3秒后中断线程
try {
Thread.sleep(3000);
thread.interrupt(); // 中断线程
} catch (InterruptedException e) {
e.printStackTrace();
}
三,线程的生命周期
线程有以下几种状态:
1. **NEW**:新建状态,线程被创建但尚未启动
2. **RUNNABLE**:可运行状态,线程正在JVM中执行或等待系统资源
3. **BLOCKED**:阻塞状态,线程等待监视器锁
4. **WAITING**:等待状态,线程无限期等待其他线程执行特定操作
5. **TIMED_WAITING**:超时等待状态,线程在指定时间内等待
6. **TERMINATED**:终止状态,线程已执行完毕
四,守护线程
守护线程是为用户线程提供服务的后台线程,当所有用户线程结束时,守护线程会自动终止。
Thread daemonThread = new Thread(new MyRunnable());
daemonThread.setDaemon(true); // 设置为守护线程
daemonThread.start();
多线程编程是一个复杂但强大的主题,掌握Thread类的基本用法是学习更高级并发编程的基础。在实际开发中,还需要注意线程安全、死锁、性能等问题。