线程基础
生命周期

创建线程
实现 Runnable 接口
class MyRunnable implements Runnable {
public void run() {
// ...
}
}
public static void main(String[] args) {
MyRunnable instance = new MyRunnable();
Thread thread = new Thread(instance);
thread.start();
}
实现 Callable 接口
class MyCallable implements Callable<String> {
public String call() {
return "著作权归@pdai所有 原文链接:https://pdai.tech/md/java/thread/java-thread-x-thread-basic.html";
}
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
MyCallable mc = new MyCallable();
FutureTask<Integer> ft = new FutureTask<>(mc);
Thread thread = new Thread(ft);
thread.start();
System.out.println(ft.get());
}
继承 Thread 类
class MyThread extends Thread {
public void run() {
// ...
}
}
public static void main(String[] args) {
MyThread mt = new MyThread();
mt.start();
}
Thread 常用方法
方法 | 作用 | 描述 |
---|---|---|
Thread() | 创建线程 | 构造方法,有不同的构造方法,能多种形式创建线程 |
start() | 启动线程 | jvm 自动调用 run 方法 |
run() | 线程的主体方法,定义线程的执行逻辑 | 不需要手动调用,jvm 自动调用 |
setName(String) | getName() | 设置和获取线程名称 | |
join() | join(millis) | 线程插队 | 在 a 线程的 run 方法体中调用 b.join(),表示加入 b 线程,会等 b 线程执行完然后继续执行 a 线程 |
sleep(long millis) | 线程休眠 | 让出 CPU ,不让出锁,时间到了再次抢夺 CPU(休眠期不会抢) |
yield() | 线程让步 | 让出 CPU ,不让出锁,可能让出 CPU 时间片后立马又被分配到了 |
currentThread() | 获取当前线程 |
等待和唤醒
- wait:让出 cpu 时间片和 锁,程序走到这里立马暂停,既然要让处锁,所以必须先持有锁,所以必须用在 synchronized 中
- notify:唤醒正在等待 同一个锁 的线程,不是随便唤醒线程,而是等待同一个锁的线程,所以也必须用在 synchronized 中
notify 不会释放锁,要等到方法执行完才会释放锁
public class WaitNotifyExample {
private final Object lock = new Object();
private boolean condition = false;
public void waitForCondition() throws InterruptedException {
synchronized (lock) {
while (!condition) { // synchronized 中的判断不能用 if 要用 while
System.out.println("让出 CPU 和锁.....");
lock.wait(); // 等待条件为真
}
System.out.println("又抢到锁和分到 cpu 时间片...");
}
}
public void setConditionTrue() {
synchronized (lock) {
condition = true;
lock.notify(); // 唤醒一个等待线程(notify 不释放锁,但是这已是方法最后一行,方法结束会释放锁)
// lock.notifyAll(); // 或者唤醒所有等待线程
}
}
public static void main(String[] args) throws InterruptedException {
WaitNotifyExample example = new WaitNotifyExample();
Runnable waitTask = () -> {
try {
example.waitForCondition();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Thread thread1 = new Thread(waitTask);
thread1.start();
Thread.sleep(2000); // 等待2秒钟
// 在主线程中设置条件为true,唤醒等待线程
example.setConditionTrue();
}
}
死锁
面试官:你告诉我什么是死锁我就录取你。候选人:你录取我我就告诉你什么是死锁
往往都是嵌套的 synchronized 导致
// 多运行几遍,如果效果不明显就两个线程获取第一把锁后分别 sleep 一会(两个线程获取的是不同的锁,第一次肯定都能获取)
public class DeadLockDemo {
// 两个锁
private static String A="A";
private static String B="B";
public static void main(String[] args){
// 线程1
new Thread(new Runnable(){
@Override
public void run(){
synchronized(A){ // 拿到 A 才进入
synchronized(B){ // 拿到 B 才进入(这时要同时具有 A 和 B)
System.out.println("AB");
}
}
}
});
// 线程2
new Thread(new Runnable(){
@Override
public void run(){
synchronized(B){
synchronized(A){ // 这时要同时具有 A 和 B
System.out.println("BA");
}
}
}
});
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具