正常情况下
public class TaskOne extends Thread {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " → " + " Start Time = " + new Date());
processCommand();
System.out.println(Thread.currentThread().getName() + " → " + " End Time = " + new Date());
}
private void processCommand() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class TaskTwo extends Thread {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " → " + " Start Time = " + new Date());
processCommand();
System.out.println(Thread.currentThread().getName() + " → " + " End Time = " + new Date());
}
private void processCommand() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
TaskOne one = new TaskOne();
TaskTwo two = new TaskTwo();
one.start();
two.start();
执行结果
第1次执行 | 第2次执行 |
---|---|
Thread-0 → Start Time = Mon May 22 21:02:57 CST 2023 | Thread-1 → Start Time = Mon May 22 21:02:29 CST 2023 |
Thread-1 → Start Time = Mon May 22 21:02:57 CST 2023 | Thread-0 → Start Time = Mon May 22 21:02:29 CST 2023 |
Thread-0 → End Time = Mon May 22 21:03:01 CST 2023 | Thread-0 → End Time = Mon May 22 21:02:32 CST 2023 |
Thread-1 → End Time = Mon May 22 21:03:01 CST 2023 | Thread-1 → End Time = Mon May 22 21:02:32 CST 2023 |
总结
如果这样写的话线程one
和线程two
是交替执行的,但是不一定谁先启动。
如何让线程one
在线程two
前先执行呢?
线程two
要在线程one
的run
里面创建,以此来保证两个线程的先后顺序
/**
* 保证two在one后面执行
*/
public class TaskTwoInOne extends Thread {
public void run() {
System.out.println(Thread.currentThread().getName() + " → " + " Start Time = " + new Date());
TaskTwo taskTwo = new TaskTwo();
taskTwo.start();
processCommand();
System.out.println(Thread.currentThread().getName() + " → " + " End Time = " + new Date());
}
private void processCommand() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
TaskTwoInOne one = new TaskTwoInOne();
one.start();
执行结果
第1次执行 | 第2次执行 |
---|---|
Thread-0 → Start Time = Mon May 22 21:11:56 CST 2023 | Thread-0 → Start Time = Mon May 22 21:13:17 CST 2023 |
Thread-1 → Start Time = Mon May 22 21:11:56 CST 2023 | Thread-1 → Start Time = Mon May 22 21:13:17 CST 2023 |
Thread-0 → End Time = Mon May 22 21:11:59 CST 2023 | Thread-1 → End Time = Mon May 22 21:13:20 CST 2023 |
Thread-1 → End Time = Mon May 22 21:11:59 CST 2023 | Thread-0 → End Time = Mon May 22 21:13:20 CST 2023 |
总结
以上只是保证,线程one
比线程two
先开始执行,但是后面就开始争抢资源不一定谁先结束。
如何让线程two
执行完再执行线程one
呢?
使用 join() 方法
public class TaskTwoJoinOne extends Thread {
public void run() {
System.out.println(Thread.currentThread().getName() + " → " + " Start Time = " + new Date());
TaskTwo two = new TaskTwo();
two.start();
try {
two.join(); // 线程two加入到线程one里,two执行完one才开始执行
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " → " + " End Time = " + new Date());
}
}
执行结果
第1次执行 | 结果分析 |
---|---|
前置条件:two.join(); | 线程two 加入到线程one 里,two 执行完 one 才开始执行 |
Thread-0 → Start Time = Mon May 22 21:24:24 CST 2023 | 线程one 开始 |
Thread-1 → Start Time = Mon May 22 21:24:24 CST 2023 | 线程two join |
Thread-1 → End Time = Mon May 22 21:24:27 CST 2023 | 线程two 执行完毕 |
Thread-0 → End Time = Mon May 22 21:24:27 CST 2023 | 线程one 执行完毕 |
前置条件:two.join(2000); | 线程two 加入到线程one 里,线程one 就等线程two 2000ms,超过2000ms后线程one 就和线程two 一起争抢资源了。如果线程two 执行完不需要2000ms,则直接执行线程one 内容,也不需要等够2000ms |
总结
这样就太给线程two
特权了,线程two
不执行完,线程one
就一直等着!!!
线程two
执行完再执行线程one
,如何给这个特权加个时效呢?
使用 join(1000) 方法
public class TaskTwoJoinOne extends Thread {
public void run() {
System.out.println(Thread.currentThread().getName() + " → " + " Start Time = " + new Date());
TaskTwo two = new TaskTwo();
two.start();
try {
two.join(1000);// 线程two加入到线程one里,就等线程two2000毫秒,超过就不等了
// two.join(6000);// 最长需等6000ms,如果线程two执行完不需要6000ms,则可以继续执行线程one的内容
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " → " + " End Time = " + new Date());
}
}