Thread class and common methods

Keywords: Java Operating System thread Process

Thread class and common methods

Common construction methods of Thread:

methodexplain
Thread( )Create thread object
Thread(Runnable target)Creating thread objects using Runnable objects
Thread(String name)Create a thread object and name it
Thread(Runnable target,String name)Use the Runnable object to create a thread object and name it

give an example:

// Thread(String name) 
public class ThreadDemo5 {
    public static void main(String[] args) {
        Thread t = new Thread("This is the name of a thread, which can be very long~"){
            @Override
            public void run() {
               while (true){

               }
            }
        };
        t.start();
    }
}

Execute and view in jconsole:

Several common properties of Thread

attributeAcquisition method
IDgetId( )
namegetName( )
stategetState() - thread state in JVM
prioritygetPriority( )
Background threadisDaemon( )
Is it aliveisAlive( )
Is it interruptedisInterrupted( )
  • ID is the unique identification of a thread, and different threads will not repeat
  • The name is used by various debugging tools
  • Status indicates the current situation of the thread
  • Threads with high priority are theoretically easier to schedule
  • One thing to remember about background threads is that the JVM will not end until all non background threads of a process have ended
  • Whether the run method is alive or not is simply understood as whether the run method is over
  • The thread interrupt problem is further explained below

Example of demonstration:

public class ThreadDemo6 {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread("HUAHua thread "){
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    //Thread.currentThread() gets the instance of the current thread. In the current code, it is equivalent to this
                    System.out.println(Thread.currentThread().getName());
                    //  The effect is the same as the uplink code
//                    System.out.println(this.getName());
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                // The execution process of run method represents the life cycle of threads in the system
                // During the execution of the run method, the kernel thread exists
                // When the run method is executed, the threads in the kernel are destroyed
                System.out.println("The thread is about to exit");
            }
        };
//        t.start();

        // As long as the thread is created, the following properties remain unchanged unless explicitly modified
        System.out.println(t.getName());
        System.out.println(t.getPriority());
        System.out.println(t.isDaemon());
        System.out.println(t.getId());

        // These properties will change with the running process of the thread
        System.out.println(t.isAlive());
        System.out.println(t.isInterrupted());
        System.out.println(t.getState());

        t.start();

        while (t.isAlive()){
            System.out.println("HUAHua The thread is running.....");
            System.out.println(t.getState());
            System.out.println(t.isInterrupted());
            Thread.sleep(300);
        }
    }
}

Supplement:
Thread.currentThread(), that is, get the instance of the current thread
In the current code, it is equivalent to this
However, not all cases can use this
be careful:
If you create a Thread by inheriting Thread, this operation is the same as this
If you use Runnable or lambda, you cannot use this at this time

At this time, run the program and output the results:
Take a small part of the output results before:

Start a thread - start()

The creation of a thread object does not mean that the thread is running
Call the start method to really create a thread at the bottom of the operating system
Creating an instance and overriding the run method tell the thread what to do, and calling the start method is the real start of execution

Interrupt a thread

Interrupt is to end a thread. There may be two situations:
① The task has been completed; That is, let the thread run finish executing (relatively mild)
② When the task is half executed, it is forced to end, that is, call the interrupt method of the thread (more intense)

There are two common thread interrupts:

  1. Communicate through shared Tags
private static boolean isQuit = false;

public static void main(String[] args) throws InterruptedException {
    // Create a thread
    Thread t = new Thread(){
        @Override
        public void run(){
            while (!isQuit){
                System.out.println("The transaction continues...");
                try {
                    Thread.sleep(500);
                }
                catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("Transaction terminated!");
        }
    };
    t.start();

    Thread.sleep(5000);
    System.out.println("Find the insider and terminate the transaction!");
    isQuit = true;
}

Output results:


The end of the above method is mild
When the flag bit is set, wait until the current loop is completed before ending the thread
For example, when the thread reaches the sleep, it has been sleeping for 100ms. At this time, isQuit is set to true. The current thread will not quit immediately, but will continue to sleep. The thread will not end until the remaining 400ms are finished

  1. Call the interrupt() method to notify
public static void main(String[] args) throws InterruptedException {
    // Create a thread
    Thread t = new Thread(){
        @Override
        public void run(){
            // Here, the internal flag of the thread is directly used to determine
            while (!Thread.currentThread().isInterrupted()){
                System.out.println("The transaction continues...");
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("Transaction terminated!");
        }
    };
    t.start();
    Thread.sleep(1000);
    System.out.println("Find the insider and terminate the transaction!");
    t.interrupt();
}

Output results:


interrupt essentially triggers an exception InterruptedException for the thread. At this time, the thread will receive this exception. How to deal with this exception is an internal matter of catch
For example, in the above code, catch only prints the call stack and does not really end the loop, so a break should be added to end the loop

If there is no break in the catch, the exception is ignored
If there is a break, triggering an exception will cause the loop to end and the thread to end


Thread receives notifications in two ways:

  • If the thread is blocked by calling wait / join / sleep and other methods, it will be notified in the form of InterruptedException exception and the interrupt flag will be cleared. When InterruptedException occurs, whether to end the thread depends on the writing method of the code in the catch. You can choose to ignore this exception or jump out of the loop to end the thread
  • Otherwise, only an internal interrupt flag is set, and the thread can pass
    Thread.interrupted() judges that the interrupt flag of the current thread is set and clears the interrupt flag (this method judges with the help of static methods in the class)
    Thread. Currentthread(). Isinterrupted() judges that the interrupt flag of the specified thread is set and does not clear the interrupt flag (this method judges with the help of the instance and then the method in the instance). In this way, the notification is received more timely. Even if the thread is sleep ing, it can be received immediately

Thread.interrupted() method:

public static void main(String[] args) {
   Thread t = new Thread(){
       @Override
       public void run() {
           for (int i = 0; i < 10; i++) {
               System.out.println(Thread.interrupted());
           }
       }
   };
   t.start();
   t.interrupt();
}

Output results:
.

Thread. Currentthread(). Isinterrupted() method:

public static void main(String[] args) {
   Thread t = new Thread(){
       @Override
       public void run() {
           for (int i = 0; i < 10; i++) {
               System.out.println(Thread.currentThread().isInterrupted());
           }
       }
   };
   t.start();
   t.interrupt();
}

Output results:
.

Think: if there is no sleep, can the new thread continue to output?
This is uncertain. Multithreads execute preemptively. If the main thread does not have a sleep, it is uncertain whether the CPU will execute the isQuit = true of the main thread or the while loop of the new thread (both possible)

For a new thread, when the run method is executed, the thread ends
For the main thread, after the main method is executed, the main thread ends

Wait for a thread - join()

The relationship between threads and threads is concurrent execution. Among multiple threads, who executes first, who executes later, and who executes where to give up the CPU is completely imperceptible to programmers, and is fully responsible by the system kernel
For example, when a new thread is created, whether the main thread continues to execute or the new thread continues to execute is not guaranteed (this is also an important feature of "preemptive execution")

It can be verified by the following code:

public static void main(String[] args) throws InterruptedException {
    Thread t = new Thread(){
        @Override
        public void run() {
            while (true){
                System.out.println("I'm a new thread!");
                try {
                    Thread.sleep(100);
                } 
                catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    };
    t.start();
    while (true){
        System.out.println("I'm the main thread!");
        Thread.sleep(100);
    }
}

Intercept some output results:

Although we can't control which thread goes first and which thread goes later, we can control which thread ends first and which thread ends later - with the help of thread waiting

For the join method, the thread executing the join method will be blocked until the execution of the corresponding thread is completed
Meaning of existence: in order to control the sequence of thread termination
A scenario of multithreading:
For example, to perform a complex operation, the main thread divides the task into several parts, and each thread calculates its own task
When all tasks are calculated separately, the main thread will summarize again (it must be ensured that the main thread is the last thread to execute)

give an example:

public static void main(String[] args) throws InterruptedException {
    Thread t1 = new Thread(){
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                System.out.println("I'm thread 1");
                try {
                    Thread.sleep(1000);
                }
                catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    };
    Thread t2 = new Thread(){
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                System.out.println("I'm thread 2");
                try {
                    Thread.sleep(1000);
                }
                catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    };
    t1.start();
    t1.join();
    t2.start();
    t2.join();
}

Output results:


Since the join of t1 is placed before the strat of t2, it means that thread 2 has not been executed at this time. t1 has blocked and waited here. Thread 2 will continue to execute until t1 ends

If you exchange t1.join() and t2.start(); The output results are as follows:


If the thread has ended, the join is called, and the join will return immediately

Gets the reference of the current thread

public static Thread currentThread() - returns a reference to the current thread object

Code example:

public static void main(String[] args) {
	Thread thread = Thread.currentThread();
	System.out.println(thread.getName());
}

Hibernate current thread

Hibernation is to block the current thread

About thread hibernation:


Posted by Locked on Wed, 24 Nov 2021 04:07:46 -0800