13 ThreadState, yield, join, getState, priority, daemon, interrupt, synchronized, thread communication

Posted by mark_john on Mon, 07 Mar 2022 22:55:53 +0100

4.13 ThreadState, yield, join, getState, priority, daemon, interrupt, synchronized, thread communication

ThreadState

Thread status:
Newborn status: new Thread()
Ready status: the start() thread will enter the ready queue and wait for the cpu to schedule
Running state: when the thread in the ready queue is scheduled by the cpu, it enters the execution state
The status of the program is not blocked, but the program cannot continue
Termination status: end of thread execution

Note:
Once a thread enters the termination state, it cannot be recovered
If a thread cannot resume running directly after its blocking state is released, it will directly enter the ready state

If a thread enters the ready state:
​ 1.start()
​ 2. Block the contact and restore the ready state
​ 3.yield to the thread. / / the current process exits the running state and enters the ready state
​ 4.cpu scheduling switching

How a thread enters a blocking state:
​ 1.sleep()
​ 2.join()
​ 3.wait()
​ 4.IO operation

How to enter termination status:
​ 1. Normal execution completed
​ 2. Add identification judgment – > recommendation
​ 3.stop discard not recommended

Exercise: countdown in the console 10 9 8 7

public class Test {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("Now start the countdown:");
        for(int i=10;i>=0;i--){
            System.out.println(i);
            Thread.sleep(1000);
        }
    }
}

yield

Comity thread

It gives more execution opportunities to other threads, but it can't decide whether other threads must execute. It depends on the scheduling of cpu

join

Queue jumping thread

join() waits for the queue jumping thread to finish executing before the current thread can continue executing
join(ms) can only wait for XXms at most

Note: you must be ready before you jump the queue

/*The father gave his son money and waited for his son to buy cigarettes before he could smoke
* When the son got the money, he went to do something else before buying cigarettes
* The son bought cigarettes for his father*/
public class JoinTest {
    public static void main(String[] args) {
        new Thread(new Fu()).start();
    }
}

class Fu implements Runnable{
    @Override
    public void run() {
        System.out.println("Give your son money to buy cigarettes");
        //The son thread needs to jump the queue and complete the thread of buying cigarettes first, so first establish a son thread to jump the queue
        Thread thread = new Thread(new Zi());
        //You must be ready before you jump the queue!
        thread.start();
        //Jump the queue for 20 seconds
        try {
            thread.join(20000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("The father took a sip of the cigarette his son bought");
    }
}

class Zi implements Runnable{
    @Override
    public void run() {
        System.out.println("My son got the money");
        for(int i=1;i<=10;i++){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(i+"s It's over....");
        }
        System.out.println("It's time for my son to buy cigarettes and go home");
    }
}

getState()

Thread status. A thread can be in one of the following states:

  • NEW
    Threads that have not been started are in this state.
  • RUNNABLE
    The thread executing in the Java virtual machine is in this state.
  • BLOCKED
    Threads that are blocked waiting for a monitor lock are in this state.
  • WAITING
    A thread that waits indefinitely for another thread to perform a specific operation is in this state.
  • TIMED_WAITING
    The thread that is waiting for another thread to perform an operation with the maximum specified wait time is in this state.
  • TERMINATED
    The exited thread is in this state.

Priority

Every thread has priority: the possibility of priority execution
The default priority of each thread is 5
Level: 1 ~ 10 1 min 10 Max

​ static int MAX_PRIORITY is the maximum priority a thread can have.
static int MIN_PRIORITY is the lowest priority a thread can have.
static int NORM_PRIORITY is the default priority assigned to the thread.

Thread - > getpriority() gets the priority of a thread
setPriority() sets the priority of a thread

Note: priority can only enlarge the opportunity of execution, and does not mean that it must be executed first or later

Daemon

Difference between daemon thread and user thread:
The daemon thread is used to guard the user thread. When the user thread is executed, the daemon thread will end directly. Its main work is garbage collection
Created thread default user thread
Garbage collector is a typical daemon thread
How to set a thread as a daemon thread: void setDaemon(boolean on) marks this thread as a daemon thread or user thread. True - > daemon thread false - > user thread
Set the daemon thread first, and then start()

public class DaemonTest {
    public static void main(String[] args) {
        Thread th = new Thread(()->{
            int i = 1;
            while (true){
                System.out.println("I'm a daemon"+i++);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        //Set daemon thread
        th.setDaemon(true);

        //Open thread
        th.start();

        //Main thread default user thread
        for(int i=1;i<=20;i++){
            System.out.println("Thread is me"+i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
} 

interrupt

​ 1.void interrupt() adds an interrupt identifier to a thread
​ 2. The static Boolean interrupted () method determines whether the current thread has been added with an interrupt ID (whether the current thread has called the interrupt() method) Reset interrupt flag at the same time
​ 3.boolean isInterrupted() determines whether the thread has added an interrupt ID, but it does not know this ID

None of the above three methods can achieve thread termination, but only add the "judgment" flag, which can be used together with break,return... If a thread is completed, it will automatically reset and clear the termination flag

public class InterruptDemo07 {
    public static void main(String[] args) {
        Thread th = new Thread(()->{
            int i = 1;
            while(true){
                System.out.println("I am th thread "+i++);
                if(Thread.interrupted()==true){
                    System.out.println("end");
                    System.out.println("Final judgment status before end"+Thread.currentThread().isInterrupted());
                    break;
                }
            }
        });
        
        th.start();

        System.out.println(th.isInterrupted());

        //Add an interrupt ID to the th thread
        th.interrupt();

        //isInterrupted() determines whether the th thread has an interrupt ID
       for(int i=1;i<=10;i++){
           System.out.println(th.isInterrupted());
           try {
               Thread.sleep(10);
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
       }
    }
}

synchronized

Thread safety:
In a multithreaded environment, only when multiple threads operate on the same resource can unsafe conditions occur

Lock mode control safety
Synchronized - > pessimistic lock

​ synchronized :
Synchronization method: synchronized modification on the method
Synchronization block: synchronized(this | class | resource) {code queued for execution}
Class Class: equivalent to the whole synchronous class. The class object is unique
This: synchronizes an object of this type and locks all resources of this object
Resources: when you only want to lock a resource of an object, you can lock only resources

The scope code of synchronization is too small, easy to lock, large scope and low efficiency

Synchronization method
Synchronized resources – > refers to the object that calls the member method
Members belong to objects
Belonging to a class

double check
Try to reduce the code range of synchronization block and improve efficiency

Synchronization method: synchronized modification on the method

Simple, but with large scope, low efficiency, and possible logic problems (in the case, outside the loop)

public class Web12306_01 implements Runnable {
    int tickets = 100; //ticket

    /*
        Ticket buying process
     */
    @Override
    public synchronized void run() {
        while(true){
            //A B C
            if(tickets<=0){
                break;
            }
            //A B C
            System.out.println(Thread.currentThread().getName()+"Purchasing item"+tickets--+"Ticket");

            //Analog network delay
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        Web12306_01 web = new Web12306_01();
        //Create 3 threads
        new Thread(web,"zhangsan").start();
        new Thread(web,"lisi").start();
        new Thread(web,"wangwu").start();
    }
}

Class Class: class object of class. When each class is loaded into memory, there will be a class object belonging to the current class, which is unique and unchanged
Simple, but class objects of one type are unique

public class Web12306_02 implements Runnable {
    int tickets = 50; //ticket

    /*
        Ticket buying process
     */
    @Override
    public void run() {
       while(true){
           //A B C
           synchronized (Web12306_02.class){
               if(tickets<=0){
                   break;
               }
               //A B C
               System.out.println(Thread.currentThread().getName()+"Purchasing item"+tickets--+"Ticket");

               //Analog network delay
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }
       }
    }

    public static void main(String[] args) {
        Web12306_02 web = new Web12306_02();
        Web12306_02 web2 = new Web12306_02();
        //Create 3 threads
        new Thread(web,"zhangsan").start();
        new Thread(web,"lisi").start();
        new Thread(web2,"wangwu").start();
    }
}

In the this-> member method, the default refers to the object of the current calling member method.

public class Web12306_03 implements Runnable {
    int tickets = 50; //ticket

    /*
        Ticket buying process
     */
    @Override
    public void run() {
       while(true){
           //A B C
           synchronized (this){
               if(tickets<=0){
                   break;
               }
               //A B C
               System.out.println(Thread.currentThread().getName()+"Purchasing item"+tickets--+"Ticket");

               //Analog network delay
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }
       }
    }

    public static void main(String[] args) {
        Web12306_03 web = new Web12306_03();
        Web12306_03 web2 = new Web12306_03();
        //Create 3 threads
        new Thread(web,"zhangsan").start();
        new Thread(web2,"lisi").start();
        new Thread(web2,"wangwu").start();
    }
}

Resources
Custom reference data type object – address of the object > new, unchanged

Lock to lock the same content, it will become locked

public class Web12306_04 implements Runnable {
    Ticket tickets = new Ticket(); //ticket

    /*
        Ticket buying process
     */
    @Override
    public void run() {
       while(true){
           //A B C
           synchronized (tickets){
               if(tickets.num<=0){
                   break;
               }
               //A B C
               System.out.println(Thread.currentThread().getName()+"Purchasing item"+tickets.num--+"Ticket");

               //Analog network delay
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }
       }
    }

    public static void main(String[] args) {
        Web12306_04 web = new Web12306_04();
        Web12306_04 web2 = new Web12306_04();
        //Create 3 threads
        new Thread(web2,"zhangsan").start();
        new Thread(web2,"lisi").start();
        new Thread(web2,"wangwu").start();
    }
}

class Ticket{
    int num = 50;
}

Thread communication

Thread communication
The wait() and notify() notifyAll() methods provided in the Object class
The premise is that it needs to be used in a synchronous environment

wait() will enter the waiting pool of an object to wait. It will be blocked and wait to be awakened
Releasing the resources of the cpu will also release the lock of the object
notify() wakes up an object, wakes up the waiting thread in the waiting pool, and wakes up a
Object locks are not released
notifyAll() wakes up all

Simulate the traffic lights of the street ,Pedestrian car public street
        street Street    traffic lights boolean flag     ns north and south -> vehicle     we thing -> people
        people  we thing    true
            Public resource Street
        vehicle  ns north and south    false

    Producer consumer model--> Signal lamp method

public class Traffic {
    public static void main(String[] args) {
        Street s = new Street();
        new Thread(new Person(s)).start();
        new Thread(new Car(s)).start();
    }
}

class Person implements Runnable{
    private Street street;
    public Person(Street street){
        this.street = street;
    }
    @Override
    public void run() {
        while (true){
            street.we();
        }
    }
}

class Car implements Runnable{
    private Street street;
    public Car(Street street){
        this.street = street;
    }
    @Override
    public void run() {
        while (true){
            street.ns();
        }
    }
}

class Street{
    boolean flag = false;//traffic lights

    //North South method: car walking
    public synchronized void ns(){
        if (flag == false){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("It's a red light now. Let's go!");
            flag = true;
            this.notify();
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    //Things people go
    public synchronized void we(){
        if (flag == true){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("It's green now. Let's go!");
            flag = false;
            this.notify();
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

Topics: Java