- 【线程 t1】代码执行完,调用【线程t2】的start()方法,【t2】执行完调用【线程t3】的start()方法;
- 使用线程间通信,3个线程使用同一把锁,【线程t1】执行完后,使用 JUC 中 signal()/signalAll() 方法唤醒【线程t2】,以此类推;
- 【推荐使用】 使用线程为我们提供的 join() 方法。
方案一备注:
代码中使用 sleep() 也是为了更方便复现问题
方案一是最 low 的一种方式,不做介绍,不建议使用
public class SortThread1 {
public static void main(String[] args) throws InterruptedException {
Thread t3 = new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(1);
System.out.println(Thread.currentThread().getName() + "线程执行完毕");
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "t3");
Thread t2 = new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName() + "线程执行完毕");
// 执行线程3
t3.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "t2");
Thread t1 = new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(2);
System.out.println(Thread.currentThread().getName() + "线程执行完毕");
// 执行线程2
t2.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
},"t1");
// 执行线程1
t1.start();
}
}
方案二
采用线程间通信。三个线程同时启动,使用一把锁。三个线程 t1,t2,t3,按顺序执行,线程 t1 执行完成后,通知线程 t2 ,t2 获取锁后,继续执行,以此类推
public class SortThread2 {
public static void main(String[] args) {
// 创建Lock
Lock lock = new ReentrantLock();
Condition condition1 = lock.newCondition();
Condition condition2 = lock.newCondition();
Condition condition3 = lock.newCondition();
Thread t1 = new Thread(() -> {
// 加锁
lock.lock();
try {
TimeUnit.SECONDS.sleep(2);
System.out.println(Thread.currentThread().getName() + "线程执行完毕");
// 唤醒t2线程
condition2.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 释放锁
lock.unlock();
}
}, "t1");
Thread t2 = new Thread(() -> {
// 加锁
lock.lock();
try {
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName() + "线程执行完毕");
// 唤醒t3线程
condition3.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 释放锁
lock.unlock();
}
}, "t2");
Thread t3 = new Thread(() -> {
// 加锁
lock.lock();
try {
TimeUnit.SECONDS.sleep(1);
System.out.println(Thread.currentThread().getName() + "线程执行完毕");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 释放锁
lock.unlock();
}
}, "t3");
// 启动线程
t1.start();
t2.start();
t3.start();
}
}
方案三
【推荐使用】使用线程为我们提供的 join() 方法。join() 方法会等待当前线程,join(0)则会一直等待线程死亡。join() 和 join(long millis) 方法源码,如下图所示:
public class SortThread3 {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(2);
System.out.println(Thread.currentThread().getName() + "线程执行完毕");
} catch (InterruptedException e) {
e.printStackTrace();
}
},"t1");
Thread t2 = new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName() + "线程执行完毕");
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "t2");
Thread t3 = new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(1);
System.out.println(Thread.currentThread().getName() + "线程执行完毕");
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "t3");
t1.start();
t1.join(); // 一直等待t1执行,线程死亡后,执行线程t2
t2.start();
t2.join(); // 一直等待t2执行,线程死亡后,执行线程t3
t3.start();
t3.join(); // 一直等待t3执行,线程死亡后,执行主线程
// 使用带参数join()方法
// t1.start();
// t1.join(10); // 等待t1线程10ms,t1线程代码内sleep 2s,则不再继续等待t1,执行t2线程
// t2.start();
// t2.join(10); // 等待t2线程10ms,t2线程代码内sleep 3s,则不再继续等待t2,执行t2线程
// t3.start();
// t3.join(10); // 等待t3线程10ms,t3线程代码内sleep 1s.因为 sleep 等待时间原因,最终输出结果是:【t3执行 > t1执行 > t2执行 > main主线程】
}
}
博主写作不易,加个关注呗
求关注、求点赞,加个关注不迷路 ヾ(◍°∇°◍)ノ゙
我不能保证所写的内容都正确,但是可以保证不复制、不粘贴。保证每一句话、每一行代码都是亲手敲过的,错误也请指出,望轻喷 Thanks♪(・ω・)ノ



