[Java programming idea] The basic cooperation mechanism of threads and the interruption of threads

wait/notify

Java defines some basic methods of thread cooperation in the Object class, wait and notify

public final void wait() throws InterruptedException;
public final native void wait(long timeout) throws InterruptedException;

A parameter with time, in milliseconds, indicates the maximum waiting time. If it is 0, it means waiting indefinitely;
one without a time parameter means waiting indefinitely. In fact, calling wait(0)
can be interrupted during the waiting period. If interrupted, InterruptedException will be thrown

Each object has a lock and a waiting queue. When a thread enters the synchronized code block, it will try to acquire the lock. If it cannot be acquired, the current thread will be added to the waiting queue. In addition to the waiting queue for locks, each object has another waiting queue, representing the condition queue, which is used for collaboration between threads.
Calling wait will put the current thread on the condition queue and block it, indicating that the current thread cannot continue to execute. It needs to wait for a condition and needs other threads to change. When other threads change the condition, the notify method of Object should be called. What notify does is to select a thread from the condition queue, remove it from the queue and wake it up

// 从条件队列中选一个线程,移除并唤醒
public final native void notify();
// 移除条件队列中所有的线程并唤醒
public final native void notifyAll();

Here is a simple example. After a thread is started, before performing an operation, it needs to wait for the instruction given to it by the main thread, and execute it after receiving the instruction.

public class WaitThread extends Thread {

    private volatile boolean fire = false;

    @Override
    public void run() {
        synchronized (this) {
            try {
                while (!fire) {
                    System.out.println("start wait");
                    wait();
                    System.out.println("wait end");
                }
                System.out.println("fire !!");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public synchronized void fire() throws InterruptedException {
        this.fire = true;
        System.out.println("notify");
        notify();
        Thread.sleep(5000);
        System.out.println("notify !!!");
    }

    public static void main(String[] args) throws InterruptedException {
        WaitThread waitThread = new WaitThread();
        waitThread.start();
        Thread.sleep(1000);
        waitThread.fire();
    }
}

The wait/notify method can only be called in the synchronized code block. There
may be doubts. Both methods are in the synchronized code block. When one thread is waiting, how can the other thread call notify?
When actually calling wait, the thread releases the object lock

The waiting thread returns from the wait call only after the synchronized block containing notify has been executed.

Collaboration Scenario

  1. Producer/Consumer Collaboration Mode: Producer threads and consumer threads cooperate through a shared queue. The producer puts data or tasks on the queue, and the consumer takes data or tasks from the queue. If the queue length is limited, when the queue is full, the producer needs to wait, and when the queue is empty, the consumer needs to wait.
    Java provides specialized blocking queue implementations:

    • Interface BlockingQueue and BlockingDeque
    • Array-based implementation class ArrayBlockingQueue
    • Linked list-based implementation classes LinkedBlockingQueue and LinkedBlockingDeque
    • Heap-based implementation class PriorityBlockingQueue
  2. Simultaneous start: requires multiple threads to start work at the same time

  3. Waiting for the end: The main thread decomposes the task into several subtasks, creates a thread for each subtask, and the main thread needs to wait for each subtask to finish executing before continuing to execute other tasks
  4. Asynchronous result
  5. Rendezvous point: For example, in parallel iterative computing, each thread is responsible for a part of the calculation, and then waits for other threads to complete at the rendezvous point. After all threads arrive, exchange data and results, and then proceed to the next iteration.

thread interruption

In Java, the main mechanism to stop a thread is interrupt. Interrupt is not a forced termination of a thread. It is a cooperative mechanism that sends a cancel signal to the thread, but it is up to the thread to decide how and when to exit.

// 返回对应线程的中断标志位是否为true
public boolean isInterrupted(); 
// 中断对应的线程
public void interrupte();
// 返回当前线程的中断标志位是否为true,同时清空中断标志位  
public static boolean interrupted();

The effect of interrupted() on the thread is related to the state of the thread and the IO operation in progress. We mainly consider the state of the thread, the impact of IO operations is related to specific IO and the operating system

RUNNABLE

If the thread runs again or has running conditions, it is just waiting for the operating system to schedule, and no IO operation is performed, interrupted() will only set the interrupt flag bit of the thread, and has no other effect.
But we can check the interrupt flag bit at the appropriate place

WAITING/TIMED_WAITING

When the thread calls the join/wait/sleep method, it will enter the WAITING/TIMED_WAITING state. At this time, calling interrupt() will cause the thread to throw an InterruptedException. After an exception is thrown, the interrupt flag will be cleared

BLOCKED

If the thread is waiting for the lock, calling interrupted() on the thread object will only set the interrupt flag of the thread, and the thread will still be in the BLOCKED state

NEW/TERMINATED

If the thread has not yet started (NEW), or has ended (TERMINATED), calling interrupted() has no effect on it.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325875265&siteId=291194637