Meet join
Simple understanding: created thread T1, ift1.join()
To the main thread, then need to wait until T1 thread execution is completed, the main thread can continue to execute
public class ThreadJoin {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
IntStream.range(1, 1000)
.forEach(i -> System.out.println(Thread.currentThread().getName() + "->" + i));
});
Thread t2 = new Thread(() -> {
IntStream.range(1, 1000)
.forEach(i -> System.out.println(Thread.currentThread().getName() + "->" + i));
});
//You must start before you can join
t1.start();
t2.start();
//Here, T1 and T2 are both join to the main thread
//So T1 and T2 are executed at the same time,
t1.join();
t2.join();
//When T1 and T2 are completed, the following code can be executed
Optional.of("All of tasks finish done.").ifPresent(System.out::println);
IntStream.range(1, 1000)
.forEach(i -> System.out.println(Thread.currentThread().getName() + "->" + i));
}
}
In the above code, T1 and T2 execute the output alternately. When the execution is completed, it is the main thread output
Of course, you can set the wait timeout
t1.start();
//The main thread waits for the T1 thread to execute for 100 milliseconds. After 20 nanoseconds, if T1 has not finished executing yet, // the main thread and T1 execute simultaneously
t1.join(100,10);
Join can be used to implement the never exit of the main thread
Thread.currentThread().join();
Meet demoan
Simple understanding: the thread created by the parent thread is set tot.setDaemon(true);
If the parent thread exits, the background thread T will also exit
public class DaemonThread {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " running");
Thread.sleep(100000);
System.out.println(Thread.currentThread().getName() + " done.");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
t.setDaemon(true);
t.start();
//If the parent thread exits after five seconds, the created t guard thread will exit together
Thread.sleep(5_000);
System.out.println(Thread.currentThread().getName());
}
}
Output:
Thread-0 running
main
The parent thread will wait five seconds to finish, and the T thread will end with the main thread
Understand the interrupt() method
Simple understanding: marking a thread with a break flag is not the end of the thread, when the thread issleep(),wait(),join()
Will throw outInterruptedException
After the exception is thrown, the interrupt flag of the thread is restored
public class InterruptTest {
public static void main(String[] args) {
Thread t1 = new Thread(()->{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println ("received flag > > > > thread interrupted");
System.out.println (T1 thread break flag after exception throw > > > "+ Thread.interrupted ());
e.printStackTrace();
}
});
t1.start();
//Ensure that the T1 thread is already executing
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
//Output flag before break
System.out.println (flag before T1 interruption > > > "+ T1. Isinterrupted());
//Interrupt thread
t1.interrupt();
}
}
Output:
Flag before T1 break > > > > false
java.lang.InterruptedException: sleep interrupted
Received flag > > > > thread interrupted
at java.lang.Thread.sleep(Native Method)
T1 thread interrupt flag after exception throw > > > false
Note: once an exception is thrown, the interrupt flag will be restored
For t.join(), the parent thread should be interrupted
//Create a thread
Thread t = new Thread() {
@Override
public void run() {
while (true) {
}
}
};
//Start thread
t.start();
//Save the parent thread
Thread main = Thread.currentThread();
//Open the second thread and interrupt the thread on the join method
Thread t3 = new Thread() {
@Override
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
//Interrupt main thread
main.interrupt();
System.out.println("interrupt");
}
};
t3.start();
try {
//Note that t.join is actually the main method
t.join();
} catch (InterruptedException e) {
System.out.println ("received interrupt signal > > >");
e.printStackTrace();
}
System.out.println ("main thread continues execution");
}
Output:
java.lang.InterruptedException
interrupt
Interrupt received > > >
The main thread continues execution
Cause: the parent thread from t.join() is the main thread. You need to interrupt the main thread to catch the interrupt exception
Use these three methods to end the thread reasonably
Scenario: if a task database queries and processes data and cannot be completed within the specified time, the thread needs to be terminated
Create an execution thread executethread in the main thread (can be understood as the main thread), and create a background thread runnerthread in the execution thread to execute the real task
runnerThread.join () to the parent thread. After a certain period of time, the processing is not completed and the execution is completed executeThread.interrupt (). Interrupt the execution thread and catch an exception. The execution thread can execute down without waiting for the runnerthread() to complete
public class ThreadService {
//Execution thread
private Thread executeThread;
//Judge whether it is finished within the specified time
private volatile boolean finished = false;
public void execute(Runnable task) {
executeThread = new Thread() {
@Override
public void run() {
Thread runner = new Thread(task);
runner.setDaemon(true);
runner.start();
try {
runner.join();
//Normal execution completed
finished = true;
} catch (InterruptedException e) {
//If an exception description is caught, the executethread is interrupted
//The process continues down and there is no need to wait for the runner to finish
//e.printStackTrace();
}
}
};
//Execution thread启动
executeThread.start();
}
public void shutdown(long mills) {
long currentTime = System.currentTimeMillis();
while (!finished) {
if ((System.currentTimeMillis() - currentTime) >= mills) {
System.out.println ("task timeout, need to end him!");
executeThread.interrupt();
break;
}
}
finished = false;
}
}
Test case:
public static void main(String[] args) {
ThreadService2 service = new ThreadService2();
long start = System.currentTimeMillis();
service.execute(() -> {
try {
//This is a simulated processing task
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
//Waiting for 10m, the task is normally finished
//service.shutdown(10000);
//Wait four seconds, the task is forced to end
service.shutdown(4000);
long end = System.currentTimeMillis();
System.out.println(end - start);
}