并发,并行,串行
- 并发:宏观上同时进行,微观上交替切换执行,单个 CPU 核心,靠快速切换任务
- 并行:同一时刻,多个任务真正同时运行,多个 CPU 核心,每个核心独立跑一个任务
- 串行:同一时刻只做一件事,做完一件再做下一件
线程
什么是线程
一个程序运行时,内部可以分成一个或多个线程,线程是CPU 执行任务的最小单位
创建线程的方式
实现 Runnable
java
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Runnable 线程:" + Thread.currentThread().getName());
}
}
public class Test {
public static void main(String[] args) {
MyRunnable r = new MyRunnable();
Thread t = new Thread(r);
t.start();
}
}
继承 Thread
java
class MyThread extends Thread {
@Override
public void run() {
System.out.println("线程运行:" + Thread.currentThread().getName());
}
}
public class Test {
public static void main(String[] args) {
MyThread t = new MyThread();
t.start(); // 启动线程
}
}
实现 Callable
java
class MyCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println("Callable 线程运行");
return 100; // 可以返回结果
}
}
public class Test {
public static void main(String[] args) throws Exception {
FutureTask<Integer> task = new FutureTask<>(new MyCallable());
Thread t = new Thread(task);
t.start();
// 获取返回值
Integer res = task.get();
System.out.println("结果:" + res);
}
}
线程池创建
java
public class Test {
public static void main(String[] args) {
// 创建线程池
ExecutorService pool = Executors.newFixedThreadPool(3);
// 提交任务
pool.submit(() -> {
System.out.println("线程池线程:" + Thread.currentThread().getName());
});
pool.shutdown(); // 关闭线程池
}
}
线程的生命周期
- 新建,创建了一个线程对象,但是没有调用 start() 方法
- 就绪,调用了 start(),等着 CPU 分配时间片,一旦拿到 CPU,就开始执行 run()
- 阻塞,线程阻塞于锁
- 等待,主动无限期等别人唤醒,例如:wait() / join() / LockSupport.park()
- 定时等待,有时间限制的等待,例如:sleep(1000) / wait(1000) / join(1000)
- 终止,run() 执行完 / 异常退出
状态的流转关系
plaintext
NEW → start() → RUNNABLE
RUNNABLE
↓ 抢锁失败
BLOCKED → 拿到锁 → RUNNABLE
RUNNABLE
↓ wait()/join()
WAITING → notify()/notifyAll() → RUNNABLE
RUNNABLE
↓ sleep(1000)
TIMED_WAITING → 时间到 → RUNNABLE
RUNNABLE → 执行完毕 → TERMINATED
如何终止线程
stop
强制杀死线程,已弃用
interrupt
java
public class Test {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
try {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("运行中...");
Thread.sleep(1000);
}
} catch (InterruptedException e) {
// 收到中断信号,退出
System.out.println("线程被中断终止");
}
});
t.start();
Thread.sleep(2000);
t.interrupt(); // 中断
}
}