Role of join()
Let the parent thread wait for the child thread to finish before continuing * ***
// Child thread public static class Child extends Thread { @Override public void run() { System.out.println("test"); // ... } } // Create a child object. At this time, the thread represented by child is in NEW state Child child = new Child(); // child represents a thread that is converted to a running state child.start(); // Wait for the child thread to finish running before continuing child.join(); System.out.println("I'll wait child Execute after running");
Thread termination related
Thread.interrupt()
- Mark the thread as terminated. It needs to be used in conjunction with Thread.interrupt() or isInterrupted() to terminate the thread.
Finally, the three methods are summarized,
- Interrupt () sets the interrupt flag for the thread;
- interrupted() is to detect an interrupt and clear the interrupt state;
- isInterrupted() only detects interrupts.
- Another important point is that interrupted () acts on the current thread,
- interrupt () and isInterrupted () act on this thread, that is, the thread represented by the instance of the method in the code.
interrupt() is just an interrupt flag
public static class MyThread extends Thread { @Override public void run() { for (int i = 0; i < 3; i++) { System.out.println("i="+(i+1)); } } }
MyThread thread=new MyThread(); thread.start(); thread.interrupt(); System.out.println("First call thread.isInterrupted(): "+thread.isInterrupted()); System.out.println("Second call thread.isInterrupted(): "+thread.isInterrupted()); System.out.println("thread Survival:"+thread.isAlive());
First call thread.isInterrupted(): true i=1 i=2 i=3 Second call thread.isInterrupted(): true thread Survival: false
It can be seen that after the interrupt () method is called, the thread continues to run without stopping,
- But the interrupt flag has been set for the thread,
- Both isInterrupted () methods will output true, which means that isInterrupted () method will not clear the interrupt state.
Interrupted print whether the current thread is interrupted
thread.start(); thread.interrupt(); System.out.println("First call thread.isInterrupted(): " + thread.isInterrupted()); System.out.println("Second call thread.isInterrupted(): " + thread.isInterrupted()); //Test interrupted() function System.out.println("First call thread.interrupted(): " + Thread.interrupted()); //System.out.println("thread.interrupted():" + thread.interrupted()) called for the second time); This won't work System.out.println("thread Survival:" + thread.isAlive());
i=1 First call thread.isInterrupted(): true i=2 i=3 Second call thread.isInterrupted(): true #Return true unchanged First call thread.interrupted(): false #Return false, and call again still returns false thread Survival: false
Why do the last two interrupted methods output false instead of the expected true and false? be careful!!! This is a pit!!!
- As mentioned above, the interrupted () method tests whether the current thread is interrupted. The current thread!!! Current thread!!! The current thread here is the main thread,
- thread.interrupt() interrupts the thread thread, which is the thread thread here.
- Therefore, the current thread main has never been interrupted, although the interrupted () method is called in the form of thread.interrupted (),
- But it still detects the main thread instead of the thread thread, so thread.interrupted () is equivalent to main.interrupted () here.
interrupted is to detect an interrupt and clear the interrupt state
Thread.currentThread().interrupt(); System.out.println("First call Thread.currentThread().interrupt(): " + Thread.currentThread().isInterrupted()); System.out.println("First call thread.interrupted(): " + Thread.interrupted()); //Thread.currentThread() System.out.println("Second call thread.interrupted(): " + Thread.interrupted());
First call Thread.currentThread().interrupt(): true First call thread.interrupted(): true Second call thread.interrupted(): false
The interrupted () method can detect interrupts and clear the interrupt status. The expected output should be true true false
interrupt really terminates the thread
If the interrupt () method is called to terminate the thread, it can be processed in the run method of the thread. For example, directly jump out of the run () method to end the thread
public class MyThread extends Thread { @Override public void run() { for (int i = 0; i < 1000; i++) { System.out.println("i="+(i+1)); //Detect whether the current thread is interrupted if(this.isInterrupted()){ System.out.println("adopt this.isInterrupted()Interrupt detected"); System.out.println("first interrupted()"+this.interrupted()); System.out.println("the second interrupted()"+this.interrupted()); break; } } System.out.println("Because an interrupt is detected, it jumps out of the loop, and the thread ends here because there is nothing left behind"); } }
MyThread2 myThread=new MyThread2(); myThread.start(); //Set interrupt status myThread.interrupt(); //sleep waits for one second until myThread runs Thread.sleep(1000); System.out.println("myThread Thread survival:"+myThread.isAlive());
i=1 adopt this.isInterrupted()Interrupt detected first interrupted()true the second interrupted()false Because an interrupt is detected, it jumps out of the loop, and the thread ends here because there is nothing left behind myThread Thread survival: false
yeild use
MyThread2 yt1 = new MyThread2("Zhang San"); MyThread2 yt2 = new MyThread2("Li Si"); yt1.start(); yt2.start();
public static class MyThread2 extends Thread { public MyThread2(String name) { super(name); } @Override public void run() { for (int i = 1; i <= 50; i++) { System.out.println("" + this.getName() + "-----" + i); // When i is 30, the thread will give up CPU time and let other threads or its own threads execute (that is, who preempts who executes first) if (i == 30) { Thread.yield(); } } } }
- When i is 30, the thread will give up CPU time and let other threads or its own threads execute (that is, who preempts who executes first)
Zhang San-----1 Zhang San-----2 Li Si-----1 Zhang San-----3 #Changed to, when Zhang San was 3, rob again: Li Si grabbed it Li Si-----2 Li Si-----3 #Li Si is 3 and grabs it again. Zhang San grabs it Zhang San-----4 Li Si-----4 Zhang San-----5 Li Si-----5
Communication between multithreads
Inter thread communication refers to the interaction between two threads, such as startup, termination, wait / wake-up.
-
start-up
There are many ways to start a thread. Refer to the chapter on Java multithreading implementation. Each implementation method here is a method in which one thread starts another thread.
-
termination
-
Thread.stop()
If you stop a thread violently, the execution of the thread will stop immediately.
-
Thread.interrupt()
Mark the thread as terminated. It needs to be used in conjunction with Thread.interrupt() or isInterrupted() to terminate the thread.
-
-
Wait / wake up
-
wait()
A thread needs to wait for another thread to complete execution. Calling wait() can make the current thread enter the wake-up queue of the current synchronization block monitor object.
-
notify() / notifyAll()
notify() is used to wake up one thread in the monitor waiting queue; notifyAll() is used to wake up all threads in the monitor waiting queue.
-
join()
Wait for the calling thread to complete execution before proceeding.
-
yeild()
Temporarily release its own resources to threads with the same priority.
-
https://blog.csdn.net/asing1elife/article/details/82905577
wait() and notify()
wait() and notify() must be used in synchronized statement blocks
- wait() forces a thread to wait
- notify() notifies a thread to continue running
public class WaitTest extends Thread { //own private final Object self; //Next object private final Object last; //Pass name, yourself and the next object through the construct public WaitTest(String name, Object self, Object last) { super(name); this.self = self; this.last = last; } @Override public void run() { for (int i = 0; i < 3; i++) { // Lock next object synchronized (last) { // Lock current object synchronized (self) { //If it is A, print the X-th run if (super.getName().equals("A")) { System.out.println("The first " + (i + 1) + " Run times!"); } //Print out name in System.out.println(super.getName()); // Wake up the current thread after waiting for the end of a cycle self.notify(); } try { // Release the object lock of the next thread last.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } public static void main(String[] args) { Object a = new Object(); Object b = new Object(); Object c = new Object(); WaitTest waitA = new WaitTest("A", a, b); WaitTest waitB = new WaitTest("B", b, c); WaitTest waitC = new WaitTest("C", c, a); waitA.start(); waitB.start(); waitC.start(); } }
First run! A B C Second run! A B C Third run! A B C
- wait() operates on the thread that has acquired the object lock
- When the thread gets the object lock, wait() initiatively releases the object lock while the thread is dormant.
- Until another thread calls notify() to wake up the thread, it does not continue to acquire the object lock and execute
- Calling notify() to wake up the thread is not real-time, but automatically releases the object lock when the execution of the corresponding synchronized statement block is completed
- Then the JVM selects the dormant thread, assigns the object lock, and executes it, so as to realize the synchronization and wake-up operations between threads
contrast
Comparison between wait() and sleep()
Both wait() and sleep() can interrupt the thread's pause state through interrupt(), so that the thread can throw InterruptedException immediately
- When you interrupt a thread through interrupt(), you only need to catch an exception in catch() to end the thread safely
- InterruptedException is thrown inside the thread, not interrupt()
- When the thread executes normal code, calling interrupt() does not throw an exception. It will only throw an exception immediately after the thread enters wait() / sleep() / join()
- Both wait() and sleep() can pause the current thread. The difference is that wait() releases the object lock while tentative
- sleep() is the static method of Thread, and wait() is the general method of Object