Summary of difficulties in java thread

1. Java thread life cycle:

 

 

 

 

5 states of thread 

1. New state (New): When the thread object pair is created, it enters the new state, such as: Thread t = new MyThread();

2. Ready state (Runnable): When the start() method (t.start();) of the thread object is called, the thread enters the ready state. A thread in the ready state just means that the thread is ready, waiting for the CPU to schedule execution at any time, to obtain the right to use the cpu, it does not mean that the thread will execute immediately after executing t.start()

3. Running state (Running): The thread in the runnable state obtains the cpu time slice (timeslice) and executes the program code. When the CPU starts to schedule the thread in the ready state, then the thread can actually execute, that is, it enters the running state. Note: The ready state is the only entry to the running state, that is, if a thread wants to enter the running state for execution, it must first be in the ready state;

4. Blocked: The thread in the running state temporarily gives up the right to use the CPU for some reason, that is, gives up the cpu timeslice, stops execution, and enters the blocked state until it is ready State, it has the opportunity to be called by the CPU again to enter the running state. Only have a chance to get cpu timeslice again and go to the running state. According to different causes of blocking, the blocking state can be divided into three types:

  1. Waiting for blocking: the thread in the running state executes the wait() method to make the thread enter the waiting blocking state; the JVM will put the thread into the waiting queue (waitting queue)
  2. Synchronous blocking: When the running thread acquires the synchronization lock of the object, if the synchronization lock is occupied by another thread and fails to acquire the synchronized synchronization lock, it will enter the synchronization blocking state, and the JVM will put the thread into the lock pool (lock pool)
  3. Other blocking: By calling sleep() or join() of the thread or issuing an I/O request, the thread will enter the blocking state. When the sleep() state times out, join() waits for the thread to terminate or time out, or the I/O processing is completed, the thread turns to the ready state again. When a running thread executes the Thread.sleep(long ms) or t.join() method, or issues an I/O request, the JVM puts the thread into a blocked state. When the sleep() state times out, join() waiting for the thread to terminate or time out, or the I/O processing is completed, the thread turns to the runnable state again

5. Dead state (Dead): When the thread finishes executing or exits the run() method due to an exception, the thread ends its life cycle.


2、sleep、yield、join、wait总结

  • sleep: release cpu resources without releasing lock resources. The method of the Thread class must take a time parameter. Will let the current thread sleep into the blocking state and release the CPU, provide opportunities for other threads to run without considering the priority, but if there is a synchronization lock, sleep will not release the lock, that is, other threads cannot obtain the synchronization lock by calling the interrupt() method Wake up sleeping threads.
  • Yield: Give up CPU scheduling , methods of the Thread class, similar to sleep, except that the user cannot specify how long to pause , and the yield() method can only allow threads of the same priority to have a chance to execute. Yield() only makes the current thread return to the executable state, so the thread that executes yield() may be executed immediately after entering the executable state . Calling the yield method is just a suggestion to tell the thread scheduler that my work has been done almost, so that other threads of the same priority can use the CPU. There is no mechanism to guarantee adoption.
  • wait: Release cpu resources and also release lock resources. The methods of the Object class (notify(), notifyAll() are also Object objects) must be placed in the loop body and the synchronization code block. The thread executing the method will release the lock and enter the thread waiting pool to wait to be awakened again (notify randomly wakes up , NotifyAll wake up, and the thread will automatically wake up after the end of the thread) and put it into the lock pool to compete for synchronization lock
  • join: Thread class method, a special kind of wait. The current running thread calls the join method of another thread, and the current thread enters the blocking state until another thread finishes and waits for the thread to terminate. Note that this method also needs to catch exceptions. Wait for the thread that called the join method to end before continuing. Such as: t.join(); is mainly used to wait for the end of the t thread . If there is no such sentence, main will be executed, resulting in unpredictable results.
join() 一直等待
join(long millis) 等待指定毫秒数
join(long millis, int nanos) 等待指定毫秒数

 


3. Summary of interrupt

background:

  1. In Java, there is no way to stop a thread immediately (Thread.stop() method has been marked as obsolete, because the stop method is too rude to stop the thread, stop the thread immediately, and do not leave room for subsequent operations such as releasing resources, and there will be safety Hidden dangers).
  2. If you want to control the state of another thread in one thread, for example: cancel a time-consuming operation. At this time, you can use java's interrupt mechanism

What is an interrupt:

  • Interruption is just a cooperative mechanism. Java does not add any syntax to interruption. The interruption process completely needs to be implemented by the programmer. To interrupt a thread, you need to manually call the interrupted method of the thread. This method only sets the interrupt flag of the thread object to true; then you need to write your own code to continuously check the flag bit of the current thread; if it is true, Indicates that another thread requires this thread to be interrupted, and you need to write code to implement what you should do at this time.
  • Each thread object has a flag to indicate whether the thread is interrupted; the flag bit is true to indicate interruption, and false to indicate uninterrupted;
  • Set the thread's flag to true by calling the interrupt method of the thread object; it can be called in other threads or in its own thread.

Related methods of interruption:

public void interrupt() 将调用者线程的中断状态设为true。
public boolean isInterrupted() 判断调用者线程的中断状态。
public static boolean interrupted 只能通过Thread.interrupted()调用。 它会做两步操作:
返回当前线程的中断状态;将当前线程的中断状态设为false;

Use of interrupt method:

/**
 * @Description 测试不同状态下线程被中断后的行为
 * @Author lhy
 * @Date 2019/11/21 15:01
 */
public class TheadStatusInterruptDemo {
    public static void main(String[] args) throws InterruptedException {
        testRunningInterrupt();
        testBlockedInterrupt();
    }

    /**
     * 测试阻塞状态下被interrupt
     * @throws InterruptedException
     */
    private static void testBlockedInterrupt() throws InterruptedException {
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                while (!Thread.currentThread().isInterrupted()) {
                    try {
                        Thread.currentThread().sleep(5000);
                    } catch (InterruptedException e) {
                        System.out.println("catch:" + Thread.currentThread().isInterrupted());
                        break;
                    }
                }
                //经过catch InterruptedException 处理后的线程中断状态已经被重置
                System.out.println("interrupted!!!:" + Thread.currentThread().isInterrupted());
            }
        });
        t1.start();
        Thread.currentThread().sleep(2000);
        t1.interrupt();
        t1.join();
    }

    /**
     * 测试运行中状态的线程被interrupt
     * @throws InterruptedException
     */
    private static void testRunningInterrupt() throws InterruptedException {
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                while (!Thread.currentThread().isInterrupted()) {
                    System.out.println("running...");
                }
                //中断处理的代码
                System.out.println("interrupted!!!" + Thread.currentThread().isInterrupted());
            }
        });
        t1.start();
        Thread.currentThread().sleep(2000);
        t1.interrupt();
        t1.join();
    }
}

 

    /**
     * 测试运行中状态的线程被interrupt
     * @throws InterruptedException
     */
    private static void testRunningAfterBlockedInterrupt() throws InterruptedException {
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                int i = 0;
                while (true) {
                    System.out.println("running...:"+i++);
                    if(i>5000){
                        try {
                            System.out.println("sleep:" +     
                            Thread.currentThread().isInterrupted());
                            //阻塞之前,interrupt被设置为true,此次会抛出异常
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            //catch中 interrupt状态位已经被自动重置为false
                            System.out.println("interrupted!!!" + 
                            Thread.currentThread().isInterrupted());
                            break;
                        }
                    }
                }
            }
        });
        t1.start();
        t1.interrupt();
        t1.join();
    }

to sum up:

  • The interrupt method simply sets the interrupt status to ture. When the interrupted thread is blocked, an exception is thrown at this time, and the interrupt status is false.
  • The interrupted method does two things, returns the current interrupted state, and clears the interrupted state. It cannot restore false to true, but can only clear true to false.
     

    To truly understand the interrupt() method, you must first understand the stop() method. In the past, a thread can be stopped by thread.stop(). Note that the stop() method can be used by one thread to stop another thread. This method is too violent and unsafe. How to say that thread A calls thread B The stop method is used to stop thread B. When this method is called, thread A actually does not know the specific execution of thread B. This sudden stop will cause some cleanup work of thread B to be unable to complete, and there is another situation that executes stop Thread B will release the lock immediately after the method, which may cause data out of synchronization problems. Based on the above problems, the stop() method has been abandoned.
In this case, the interrupt() method appears. It is different from stop. It does not actually stop a thread. It just sends a signal to the thread telling it that it should end (set a stop flag). The really safe approach is to let the thread end itself instead of letting one thread end another thread.

    Through the cooperation of the interrupt() and .interrupted() methods, it is possible to stop a thread normally. Thread A informs thread B to end the thread by calling the interrupt method of thread B. Inside the run method of thread B, a loop check is passed. Whether the .interrupted() method is true to receive the signal of thread A, if it is true, an exception can be thrown, some clean-up work is done in the catch, and then the thread is terminated. Thread.interrupted() will clear the flag bit. It does not mean that the thread has resumed. It can be understood as only that it has responded to the interrupt signal and then reset it to a state where it can receive the signal again. From beginning to end, understand a key point, the interrupt() method just changes the value of a flag bit, and it is not necessarily related to the state of the thread.

 

 

 

Guess you like

Origin blog.csdn.net/qq_36807862/article/details/105988368