Java Thread State and Operation Method of Synchronization Lock

  • 2021-12-11 18:07:40
  • OfStack

The life course of thread

5 states of a thread

Creation state: In short, when the code that creates the thread object appears, the thread enters the creation state. At this time, the thread is just a line of code. Only when the thread's start () method is called will the state of the thread change and enter the ready state
Ready state: The thread in this state is ready to run at any time, but it does not mean that it will start running immediately. You also need to wait for the random scheduling and random operation of CPU. Only when the thread is successfully scheduled and run by CPU, the thread at this time can be regarded as entering the next state-running state.
Running state: The thread is running, mainly the code block in the running thread.
Blocking state: During the running of a thread, when sleep (), yield (), synchronous lock or other methods that block the thread are called in the thread code block, the thread cannot continue to run at this time and enters the blocking state (the logic confusion of the thread code block itself can also block the thread). When the blocking event that caused the thread to block is resolved, the thread does not return to the running state, but returns to the ready state and waits for the scheduled run of CPU again. It should be noted that blocking does not mean that the thread runs terminated
Dead state: When the thread successfully runs all the code, the thread ends and enters the dead state. Once thread 1 dies, it cannot be started again. Note the difference between this and blocking state. Similarly, when a thread is forced to end and terminate when it is running for one and a half years, it is also considered to be dead and cannot be started again.

Method of thread

The thread class in Java has its own methods for threads, which can make threads sleep, cut queues, improve the priority of thread scheduling, etc. They provide operational means to change the state of threads. (However, in the JDK help documentation, some methods are no longer recommended.)

One of the interesting things about threaded methods

Thread sleep is in milliseconds. One second equals one thousand milliseconds. 1, the sleep method is called in the test program to improve the occurrence of program problems, or to find bug Thread stop, because the stop method in Java is not very easy to use, so I generally write a stop method by myself, calibrate a Boolean Flag as a sign of thread execution, and run when flag is true, and stop when flag is false. Thread comity is to pause a running thread back to the ready state, instead of becoming blocked. Interestingly, comity is not necessarily successful, because threads from ready to run are randomly scheduled by CPU. Therefore, it is possible for courteous threads to schedule and run ahead of time in the next scheduling. Thread queue jumping (join method), forcing other threads to block, and other threads can continue to execute only after the inserted thread completes execution Although threads have priority differences (1-10), in actual operation, they still have to look at the mood scheduling operation of CPU. High priority is only 1 point higher than the probability of being scheduled. Viewing and changing methods with thread priority in Java (priority setting of threads is best before thread startup)

public class ttp {
    public static void main(String[] args) {
        // Default priority of main thread 
        System.out.println(Thread.currentThread().getName()+"--->" + Thread.currentThread().getPriority());
        MyPriorty mm = new MyPriorty();
        Thread t1 = new Thread(mm);
        Thread t2 = new Thread(mm);
        Thread t3 = new Thread(mm);


        
        t1.setPriority(10);
        t1.start();

        t2.setPriority(4);
        t2.start();

        t3.setPriority(6);
        t3.start();


    }
}

//Runnable Interface implementation interface, run Method to print the thread name and the priority of the thread 
class MyPriorty implements Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"--->" + Thread.currentThread().getPriority());
    }
}
// The output here has many results, because priority only increases the probability that the thread will be scheduled to run 

User threads and daemon threads. The role of the daemon thread is to ensure the normal execution process of the user thread, such as the memory recovery thread in Java and the background recording operation log, etc. These are daemon threads. The virtual machine must wait for the user thread to finish executing, instead of waiting for the daemon thread to finish executing. When the user thread completes, the virtual machine automatically shuts down and the daemon thread automatically dies.


//Java Adj. Thread Class comes with a method to set the daemon thread 
Thread.setdaemon(true) // Set as a daemon thread 
//1 All threads we create are user threads by default 

Thread synchronization. Thread synchronization is a problem that must be considered when multiple threads access the same object and all want to operate on it. Multithreading without thread synchronization (concurrency) control is unsafe.


// Thread is unsafe and appears -1 Ticket and two threads get the same 1 Ticket error, so this is 1 Unsafe threads 
public class test05 {

    public static void main(String[] args) {
        buyTicket b1 = new buyTicket();
        Thread t1 = new Thread(b1,"you");
        Thread t2 = new Thread(b1,"i");
        Thread t3 = new Thread(b1,"he");
        Thread t4 = new Thread(b1,"she");
        t1.start();
        t2.start();
        t3.start();
        t4.start();

    }
}


class buyTicket implements Runnable{
    // Remaining votes 
    private int ticketNums = 12;
    private boolean flag = true;

    @Override
    public void run() {
        while(flag){
            buy();
        }
    }

    private void buy(){
        if(ticketNums <= 0){
            flag = false;
            return;
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + " I bought the first " + ticketNums-- + " A ticket ");
    }
}

Thread synchronization

Thread synchronization is essentially a waiting mechanism. When threads are synchronized, multiple threads are put into the object waiting pool for queuing, waiting for the first thread to finish the operation, and then the next thread to execute the operation. Each object has a unique lock (exclusive lock), and each thread will obtain the exclusive lock of the object when executing, so that only the thread that obtains the lock can operate on the object, and the other lock will be obtained by the next thread after execution. To sum up, the formation condition of thread synchronization is: queue + lock.

When accessing the lock mechanism synchronized, when one thread obtains the exclusive lock of the object and monopolizes the resources, other threads must wait and release the lock after using it

Thread synchronization also has some problems (most of which are at the expense of performance to ensure security)

Holding a lock by 1 thread will cause all other threads that need this lock to hang In multi-thread contention, locking and releasing locks will lead to more context switching and scheduling delay, which will cause performance problems If a high-priority thread waits for a low-priority thread to release the lock, it will cause priority inversion and cause performance problems

1 Generally speaking, synchronized is added in the method declaration, and locks are added to this object resources in the method by default. If you want to lock other shared resource objects, use synchronization monitor

Thread 1 accesses, locks the monitor, and starts executing the intermediate code Thread 2 accessed and found that the monitor was locked, inaccessible and suspended Thread 1 is finished, unlock the monitor Thread 2 access, monitor unlocked, lock and execute code

public void xxx(){
    // Among them ob Is any shared resource object you want to lock 
    // The code block is placed in the synchronization monitor 
    synchronized(obj){
        ....
    }
}

It should be noted that such a lock is feasible in theory, but although it is added in actual operation, it may still appear unsafe phenomenon


Related articles: