12 Thread dormancy sleep, thread polite yield, use of Thread.join(), thread expired suspend(), resume() and stop()

Java multithreading common methods, expired methods

    • thread sleep sleep
    • Thread courtesy yield
    • Use of Thread.join()
    • Suspend(), resume() and stop() for thread expiration

Thread sleep sleep

  • sleep(long) specifies the number of milliseconds that the current thread blocks
  • There is an exception in sleep InterruptException
  • After the sleep time is up, the thread enters the ready state
  • sleep can simulate network delay
  • Every object has a lock, sleep will not release the lock

Thread yield

yield() suspends the current thread, changing the current thread from the running state to the ready state,

Let the cpu reschedule. As for which thread execution is selected by the cpu, it is random and depends entirely on the cpu scheduling.

public class ThreadYield {<!-- -->
    public static void main(String[] args) {<!-- -->
        MyYield myYield = new MyYield();
        new Thread(myYield,"A").start();
        new Thread(myYield,"B").start();

    }
}

class MyYield implements Runnable{<!-- -->

    @Override
    public void run() {<!-- -->
        System.out.println(Thread.currentThread().getName() + "start...");
        Thread. yield();
        System.out.println(Thread.currentThread().getName() + "stop...");
    }
}

Execution result

Execute it several times, you will find different results

A start...
B start...
A stop...
B stop...

Use of Thread.join()

When a thread A executes B.join(), the current thread A waits for the B thread to terminate before executing the rest of thread A.

join() guarantees the visibility of thread B, that is, the variables modified in thread B are visible to thread A.

/**
 * Thread join method
 */
public class Join {<!-- -->
    public static void main(String[] args) throws Exception {<!-- -->
        Thread previous = Thread. currentThread();
        for (int i = 0; i < 10; i ++ ) {<!-- -->
            // Each thread has a reference to the previous thread and needs to wait for the previous thread to terminate before returning from the wait
            Thread thread = new Thread(new Domino(previous), String. valueOf(i));
            thread. start();
            previous = thread;
        }
        TimeUnit. SECONDS. sleep(5);
        System.out.println(Thread.currentThread().getName() + "terminate.");
    }

    static class Domino implements Runnable {<!-- -->
        private Thread thread;

        public Domino(Thread thread) {<!-- -->
            this. thread = thread;
        }

        public void run() {<!-- -->
            try {<!-- -->
                thread. join();
            } catch (InterruptedException e) {<!-- -->
            }
            System.out.println(Thread.currentThread().getName() + "terminate.");
            try {<!-- -->
                TimeUnit. SECONDS. sleep(1);
            } catch (InterruptedException e) {<!-- -->
                e.printStackTrace();
            }
        }
    }

}
main terminate.
0 terminate.
1 terminate.
2 terminate.
3 terminate.
4 terminate.
5 terminate.
6 terminate.
7 terminate.
8 terminate.
9 terminate.

Process finished with exit code 0

The premise of the termination of each thread is the termination of the predecessor thread, and each thread waits for the termination of the predecessor thread before returning from the join() method.

The join method is equivalent to jumping into the queue for execution. Main is the first to jump into the queue, and the order is 0-9, so the execution sequence is as above.

a.join() method, wait for thread a to finish executing, and then execute other threads, and other threads are blocked

public class ThreadJoin {<!-- -->

    public static void main(String[] args) throws InterruptedException {<!-- -->
        MyJoin myJoin = new MyJoin();

        Thread t1 = new Thread(myJoin, "Zhang San");
        t1. start();

        for (int i = 0; i < 200; i ++ ) {<!-- -->
            Thread. sleep(50);
            System.out.println("Wang Wu execution to " + i);
            if (i==100){<!-- -->
                t1. join();
            }
        }

    }

}

class MyJoin implements Runnable{<!-- -->

    @Override
    public void run() {<!-- -->
        for (int i = 0; i < 100; i ++ ) {<!-- -->
            try {<!-- -->
                Thread. sleep(100);
            } catch (InterruptedException e) {<!-- -->
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " execute to " + i);
        }
    }
}

Suspend(), resume() and stop() for thread expiration

suspend suspend()

resume resume()

stop stop()

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * expired method
 * suspend suspend()
 * resume resume()
 * resume stop()
 * Like the buttons of a music player
 */
public class Deprecated {<!-- -->
    public static void main(String[] args) throws Exception {<!-- -->
        DateFormat format = new SimpleDateFormat("HH:mm:ss");
        Thread printThread = new Thread(new Runner(), "PrintThread");
        printThread. setDaemon(true);
        printThread. start();
        TimeUnit. SECONDS. sleep(3);
        // Pause the PrintThread, the output work stops
        printThread. suspend();
        System.out.println("main suspend PrintThread at " + format.format(new Date()));
        TimeUnit. SECONDS. sleep(3);
        // Restore the PrintThread, and the output continues
        printThread. resume();
        System.out.println("main resume PrintThread at " + format.format(new Date()));
        TimeUnit. SECONDS. sleep(3);
        // Terminate the PrintThread, the output content stops
        printThread. stop();
        System.out.println("main stop PrintThread at " + format.format(new Date()));
        TimeUnit. SECONDS. sleep(3);
    }

    static class Runner implements Runnable {<!-- -->
        @Override
        public void run() {<!-- -->
            DateFormat format = new SimpleDateFormat("HH:mm:ss");
            while (true) {<!-- -->
                System.out.println(Thread.currentThread().getName() + " Run at " +
                        format. format(new Date()));
                try {<!-- -->
                    TimeUnit. SECONDS. sleep(1);
                } catch (InterruptedException e) {<!-- -->
                    e.printStackTrace();
                }
            }
        }
    }

}
//execution result
PrintThread Run at 21:30:27
PrintThread Run at 21:30:28
PrintThread Run at 21:30:29
main suspend PrintThread at 21:30:30
PrintThread Run at 21:30:33
main resume PrintThread at 21:30:33
PrintThread Run at 21:30:34
PrintThread Run at 21:30:35
main stop PrintThread at 21:30:36

Process finished with exit code 0

The main reasons why is not recommended are as follows: Take the suspend() method as an example. After calling, the thread will not release the resources (such as locks) it has already occupied, but will enter the sleep state while occupying the resources, which is easy to cause deadlock. question. Similarly, the stop() method does not guarantee the normal release of the thread's resources when terminating a thread, and usually does not give the thread a chance to complete the resource release work, so the program may work in an uncertain state.