Common methods of thread communication: Join interrupt wait notify yeld interrupted isinterrupted

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

Tags: Java thread

Posted on Mon, 22 Nov 2021 14:51:32 -0500 by staffanolin