table of Contents
Preface
In many cases, the main thread creates and runs the sub-threads. If a lot of time-consuming operations are required in the sub-threads, the main thread often ends earlier than the sub-threads.
If the main thread wants to wait for the execution of the child thread to complete before executing. For example, the child thread processes a data operation, and the main thread wants to obtain this data, you can use the join method.
public final void join() throws InterruptedException
等待该线程终止。
抛出:
InterruptedException - 如果任何线程中断了当前线程。当抛出该异常时,当前线程的中断状态被清除。
join()
public class Demo15 {
public static void main(String[] args) throws InterruptedException {
Demo15Thread t = new Demo15Thread();
t.start();
System.out.println("等待子线程运算");
//等待该线程结束
t.join();
System.out.println("主线程结束");
}
}
class Demo15Thread extends Thread{
@SneakyThrows
@Override
public void run() {
//模拟大强度运算
Thread.sleep(1500);
System.out.println("子线程计算的值为: "+9584623333135895L);
}
}
in conclusion
join与synchronized
Join internally uses wait() for waiting, while synchronized internally uses [object lock] for synchronization.
join与sleep
public class Demo15 {
public static void main(String[] args) throws InterruptedException {
Demo15ThreadA threadA = new Demo15ThreadA();
Demo15ThreadB threadB = new Demo15ThreadB(threadA);
Demo15ThreadC threadC = new Demo15ThreadC(threadA);
threadB.start();
threadC.start();
}
}
class Demo15ThreadA extends Thread{
@SneakyThrows
@Override
public void run() {
System.out.println("线程A开始于:" + System.currentTimeMillis());
Thread.sleep(1000);
System.out.println("线程A结束于:" + System.currentTimeMillis());
}
public synchronized void getTime(){
System.out.println("方法执行时间: "+System.currentTimeMillis());
}
}
class Demo15ThreadB extends Thread{
private Demo15ThreadA threadA;
public Demo15ThreadB(Demo15ThreadA threadA){
this.threadA = threadA;
}
@SneakyThrows
@Override
public void run() {
synchronized (threadA){
threadA.start();
//sleep会导致线程阻塞,不会释放锁
Thread.sleep(2000L);
//join(long)内部使用wait(long),所以它会释放同步锁
//threadA.join(2000L);
while(true){
}
}
}
}
class Demo15ThreadC extends Thread{
private Demo15ThreadA threadA;
public Demo15ThreadC(Demo15ThreadA threadA){
this.threadA = threadA;
}
@Override
public void run() {
threadA.getTime();
}
}
in conclusion
- Join internally uses wait() for waiting, while synchronized internally uses [object lock] for synchronization.
- Sleep(long) will cause the thread to block and
不会
release the synchronization lock. Join(long) uses wait(long) internally to会
release the synchronization lock.
join and exception
public class Demo16 {
public static void main(String[] args) throws InterruptedException {
Demo16ThreadB threadB = new Demo16ThreadB();
threadB.start();
//使threadB优先执行
Thread.sleep(300);
Demo16ThreadC threadC = new Demo16ThreadC(threadB);
threadC.start();
}
}
class Demo16ThreadA extends Thread{
@Override
public void run() {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
// 模拟耗时操作
String s = new String();
Math.random();
}
}
}
class Demo16ThreadB extends Thread{
@Override
public void run() {
try {
Demo16ThreadA t = new Demo16ThreadA();
t.start();
//t线程加入到Demo16ThreadB中
t.join();
System.out.println("Demo16ThreadB线程正常结束");
} catch (InterruptedException e) {
System.out.println("Demo16ThreadB线程异常结束");
e.printStackTrace();
}
}
}
class Demo16ThreadC extends Thread{
private Demo16ThreadB threadB;
public Demo16ThreadC(Demo16ThreadB threadB){
this.threadB = threadB;
}
@Override
public void run() {
//模拟InterruptedException,中断Demo16ThreadB
threadB.interrupt();
}
}
operation result
in conclusion
Although Demo16ThreadB was abnormally terminated, Demo16ThreadA is still running normally.