Java multithreading Foundation

Posted by cachemony on Mon, 07 Mar 2022 04:37:14 +0100

catalogue

1, Basic thread usage

1. Two ways to create threads

2. Thread application case 1 - inherit thread class

3. Thread application case - Implementation of Runnable interface

4. Thread application case - multithreaded execution

5. How do threads understand

2, The difference between inheriting thread and implementing Runnable

1. Code case

3, Thread termination

1. Basic description

2. Application case

4, Common thread methods

1. Common methods group I

2. Precautions and details

3. The second group of common methods

4. User thread and daemon thread

5, Thread life cycle

1. Thread. Is used in JDK The state enumeration represents several states of a thread

2. Thread state transition diagram

3. Write a program to view the thread status

6, Thread synchronization

1. Thread synchronization mechanism

2. Synchronization specific method - Synchronized

3. Analyze the principle of synchronization

7, Mutex

1. Basic introduction

2. Use mutex lock to solve ticket selling problem

3. Precautions and details

8, Thread deadlock

1. Basic introduction

9, Release lock

1. The following operation will release the lock

2. The following operation will not release the lock

1, Basic thread usage

1. Two ways to create threads

2. Thread application case 1 - inherit thread class

public class Thread01 {
    public static void main(String[] args) throws InterruptedException {

        //Create a Cat object that can be used as a thread
        Cat cat = new Cat();

        // Read source code
        /*(1)
        public synchronized void start () {
            start0();
        }
        (2)
        // start0() It is a local method, a JVM call, and the bottom layer is a c/c + + implementation
        // The real effect of multithreading is start0(), not run
        private native void start0();*/

        cat.start();//Start the thread - > the run method of cat will eventually be executed

        //cat. run();// The run method is an ordinary method. If a thread is not really started, the run method will be executed until it is completed
        //Note: when the main thread starts a sub thread thread Thread-0, the main thread will not block and will continue to execute
        //At this time, the main thread and sub thread execute alternately
        System.out.println("The main thread continues execution" + Thread.currentThread().getName());//Name main
        for (int i = 0; i < 60; i++) {
            System.out.println("Main thread i=" + i);
            //Hibernate the main thread
            Thread.sleep(1000);
        }
    }
}

// explain
// 1. When a class inherits the Thread class, it can be used as a Thread
// We will rewrite our own code
// 3. The run thread class implements the run method of the Runnable interface
    /*@Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }*/

class Cat extends Thread {
    int times = 0;

    @Override
    public void run() {//Rewrite the run method and write your own business logic
        while (true) {
            //The thread every 1 second. Output "meow meow, I'm a kitten" on the console
            System.out.println("Meow meow, I'm a kitten" + (++times) + " Thread name=" + Thread.currentThread().getName());
            //Let the thread sleep for 1 second ctrl+alt+t
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (times == 80) {
                break;//When the times reaches 80, exit while, and the thread will exit..}
            }
        }
    }
}

3. Thread application case - Implementation of Runnable interface

// package com.hspedu.threaduse;    This guide package is required at runtime

public class Thread02 {
    public static void main(String[] args) {
        Dog dog = new Dog();
        //dog.start();  Start cannot be called here
        //Create a Thread object and put the dog object (Runnable) into the Thread
        Thread thread = new Thread(dog);
        thread.start();

//        Tiger tiger = new Tiger();// Runnable is implemented
//        ThreadProxy threadProxy = new ThreadProxy(tiger);
//        threadProxy.start();
    }
}

class Animal {
}

class Tiger extends Animal implements Runnable {

    @Override
    public void run() {
        System.out.println("The tiger howled....");
    }
}

//Thread agent class simulates a minimalist thread class
class ThreadProxy implements Runnable {//You can treat the Proxy class as ThreadProxy

    private Runnable target = null;//Property, type Runnable

    @Override
    public void run() {
        if (target != null) {
            target.run();//Dynamic binding (running type Tiger)
        }
    }

    public ThreadProxy(Runnable target) {
        this.target = target;
    }

    public void start() {
        start0();//This method is really a multithreaded method
    }

    public void start0() {
        run();
    }
}


class Dog implements Runnable { //Develop threads by implementing Runnable interface

    int count = 0;

    @Override
    public void run() { //Common method
        while (true) {
            System.out.println("The dog barked..hi" + (++count) + Thread.currentThread().getName());

            //Sleep for 1 second
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            if (count == 10) {
                break;
            }
        }
    }
}

4. Thread usage case - multithreaded execution

//  package com.hspedu.threaduse;      This guide package is necessary when running

/**
 * main Thread starts two child threads
 */
public class Thread03 {
    public static void main(String[] args) {

        T1 t1 = new T1();
        T2 t2 = new T2();
        Thread thread1 = new Thread(t1);
        Thread thread2 = new Thread(t2);
        thread1.start();//Start the first thread
        thread2.start();//Start the second thread
        //...

    }
}

class T1 implements Runnable {

    int count = 0;

    @Override
    public void run() {
        while (true) {
            //Output "hello,world" every 1 second and output 10 times
            System.out.println("hello,world " + (++count));
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if(count == 60) {
                break;
            }
        }
    }
}

class T2 implements Runnable {

    int count = 0;

    @Override
    public void run() {
        //Output "hi" every 1 second for 5 times
        while (true) {
            System.out.println("hi " + (++count));
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if(count == 50) {
                break;
            }
        }
    }
}

5. How do threads understand

2, The difference between inheriting thread and implementing Runnable

1. Code case

    //package com.hspedu.ticket;    This guide package must be imported at runtime

/**
 * Using multithreading, simulate three windows to sell 100 tickets at the same time
 */
public class SellTicket {
    public static void main(String[] args) {

        //test
//        SellTicket01 sellTicket01 = new SellTicket01();
//        SellTicket01 sellTicket02 = new SellTicket01();
//        SellTicket01 sellTicket03 = new SellTicket01();
//
//        //We'll oversold here
//        sellTicket01.start();// Start ticket selling thread
//        sellTicket02.start();// Start ticket selling thread
//        sellTicket03.start();// Start ticket selling thread


        System.out.println("===Use the implementation interface to sell tickets=====");
        SellTicket02 sellTicket02 = new SellTicket02();

        new Thread(sellTicket02).start();//Thread 1 - window
        new Thread(sellTicket02).start();//2nd thread - window
        new Thread(sellTicket02).start();//3rd thread - window


    }
}


//Using Thread mode

class SellTicket01 extends Thread {

    private static int ticketNum = 100;//Let multiple threads share ticketNum

    @Override
    public void run() {
        while (true) {

            if (ticketNum <= 0) {
                System.out.println("End of ticket sales...");
                break;
            }

            //Sleep for 50 ms, analog
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("window " + Thread.currentThread().getName() + " Sell a ticket"
                    + " Remaining votes=" + (--ticketNum));

        }
    }
}



//Implementation interface mode
class SellTicket02 implements Runnable {
    private int ticketNum = 100;//Let multiple threads share ticketNum

    @Override
    public void run() {
        while (true) {

            if (ticketNum <= 0) {
                System.out.println("End of ticket sales...");
                break;
            }

            //Sleep for 50 ms, analog
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("window " + Thread.currentThread().getName() + " Sell a ticket"
                    + " Remaining votes=" + (--ticketNum));//1 - 0 - -1  - -2

        }
    }
}

3, Thread termination

1. Basic description

2. Application case

public class ThreadExit_ {
    public static void main(String[] args) throws InterruptedException {
        T t1 = new T();
        t1.start();

        //If you want the main thread to control the termination of the t1 thread, you must be able to modify the loop
        //Let t1 exit the run method, thus terminating the t1 thread - > notification mode

        //Let the main thread sleep for 10 seconds, and then notify t1 thread to exit
        System.out.println("main Thread sleep 10 s...");
        Thread.sleep(10 * 1000);
        t1.setLoop(false);
    }
}

class T extends Thread {
    private int count = 0;
    //Set a control variable
    private boolean loop = true;
    @Override
    public void run() {
        while (loop) {

            try {
                Thread.sleep(50);// Let the current thread sleep for 50ms
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("T In operation...." + (++count));
        }

    }

    public void setLoop(boolean loop) {
        this.loop = loop;
    }
}

4, Common thread methods

1. Common methods group I

2. Precautions and details

3. The second group of common methods

package com.hspedu.method;

public class ThreadMethod02 {
    public static void main(String[] args) throws InterruptedException {

        T2 t2 = new T2();
        t2.start();

        for(int i = 1; i <= 20; i++) {
            Thread.sleep(1000);
            System.out.println("Main thread(Little brother) Yes " + i  + " steamed stuffed bun");
            if(i == 5) {
                System.out.println("Main thread(Little brother) Let child thread(boss) Eat first");
                //join, thread queue
                //t2.join();//  This is equivalent to letting the T2 thread execute first
                Thread.yield();//Comity is not necessarily successful
                System.out.println("thread (boss) Finished the main thread(Little brother) Keep eating..");
            }

        }
    }
}

class T2 extends Thread {
    @Override
    public void run() {
        for (int i = 1; i <= 20; i++) {
            try {
                Thread.sleep(1000);//Sleep for 1 second
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Child thread(boss) Yes " + i +  " steamed stuffed bun");
        }
    }
}

4. User thread and daemon thread

package com.hspedu.method;

public class ThreadMethod03 {
    public static void main(String[] args) throws InterruptedException {
        MyDaemonThread myDaemonThread = new MyDaemonThread();
        //If we want the main thread to end, the child thread will end automatically
        //, just set the child thread as the daemon thread
        myDaemonThread.setDaemon(true);
        myDaemonThread.start();

        for( int i = 1; i <= 10; i++) {//main thread
            System.out.println("Baoqiang is working hard...");
            Thread.sleep(1000);
        }
    }
}

class MyDaemonThread extends Thread {
    public void run() {
        for (; ; ) {//Infinite loop
            try {
                Thread.sleep(1000);//Sleep for 1000 milliseconds
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Ma Rong and Song Zhe chat happily, ha ha ha~~~");
        }
    }
}

5, Thread life cycle

1. Thread. Is used in JDK The state enumeration represents several states of a thread

2. Thread state transition diagram

3. Write a program to check the thread status

package com.hspedu.state_;

public class ThreadState_ {
    public static void main(String[] args) throws InterruptedException {
        T t = new T();
        System.out.println(t.getName() + " state " + t.getState());
        t.start();

        while (Thread.State.TERMINATED != t.getState()) {
            System.out.println(t.getName() + " state " + t.getState());
            Thread.sleep(500);
        }

        System.out.println(t.getName() + " state " + t.getState());

    }
}

class T extends Thread {
    @Override
    public void run() {
        while (true) {
            for (int i = 0; i < 10; i++) {
                System.out.println("hi " + i);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            break;
        }
    }
}

6, Thread synchronization

1. Thread synchronization mechanism

2. Synchronization specific method - Synchronized

3. Analyze the principle of synchronization

7, Mutex

1. Basic introduction

2. Use mutex lock to solve ticket selling problem

Code: there are two methods, code block locking and method locking

package com.hspedu.syn;

/**
 * Using multithreading, simulate three windows to sell 100 tickets at the same time
 */
public class SellTicket {
    public static void main(String[] args) {

        //test
//        SellTicket01 sellTicket01 = new SellTicket01();
//        SellTicket01 sellTicket02 = new SellTicket01();
//        SellTicket01 sellTicket03 = new SellTicket01();
//
//        //We'll oversold here
//        sellTicket01.start();// Start ticket selling thread
//        sellTicket02.start();// Start ticket selling thread
//        sellTicket03.start();// Start ticket selling thread


//        System.out.println("= = = use the implementation interface to sell tickets = = = =");
//        SellTicket02 sellTicket02 = new SellTicket02();
//
//        new Thread(sellTicket02).start();// Thread 1 - window
//        new Thread(sellTicket02).start();// 2nd thread - window
//        new Thread(sellTicket02).start();// 3rd thread - window

        //Test one
        SellTicket03 sellTicket03 = new SellTicket03();
        new Thread(sellTicket03).start();//Thread 1 - window
        new Thread(sellTicket03).start();//2nd thread - window
        new Thread(sellTicket03).start();//3rd thread - window

    }
}


//Realize the interface mode, and use synchronized to realize thread synchronization
class SellTicket03 implements Runnable {
    private int ticketNum = 100;//Let multiple threads share ticketNum
    private boolean loop = true;//Control run method variables
    Object object = new Object();


    //The lock of the synchronous method (static) is the current class itself
    //Lao Han's interpretation
    //1. The public synchronized static void m1() {} lock is added to sellticket03 class
    //2. If in a static method, implement a synchronous code block
    /*
        synchronized (SellTicket03.class) {
            System.out.println("m2");
        }
     */
    public synchronized static void m1() {

    }
    public static  void m2() {
        synchronized (SellTicket03.class) {
            System.out.println("m2");
        }
    }

    // explain
    //1. public synchronized void sell() {} is a synchronization method
    //2. Lock this object at this time
    //3. You can also write synchronize on the code block, synchronize the code block, and the mutex is still in this object
    public /*synchronized*/ void sell() { //Synchronous method. At the same time, only one thread can execute the sell method

        synchronized (/*this*/ object) {
            if (ticketNum <= 0) {
                System.out.println("End of ticket sales...");
                loop = false;
                return;
            }

            //Sleep for 50 ms, analog
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("window " + Thread.currentThread().getName() + " Sell a ticket"
                    + " Remaining votes=" + (--ticketNum));//1 - 0 - -1  - -2
        }
    }

    @Override
    public void run() {
        while (loop) {

            sell();//The sell method is a common synchronization method
        }
    }
}

//Using Thread mode
// new SellTicket01().start()
// new SellTicket01().start();
class SellTicket01 extends Thread {

    private static int ticketNum = 100;//Let multiple threads share ticketNum

//    public void m1() {
//        synchronized (this) {
//            System.out.println("hello");
//        }
//    }

    @Override
    public void run() {


        while (true) {

            if (ticketNum <= 0) {
                System.out.println("End of ticket sales...");
                break;
            }

            //Sleep for 50 ms, analog
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("window " + Thread.currentThread().getName() + " Sell a ticket"
                    + " Remaining votes=" + (--ticketNum));

        }
    }
}


//Implementation interface mode
class SellTicket02 implements Runnable {
    private int ticketNum = 100;//Let multiple threads share ticketNum

    @Override
    public void run() {
        while (true) {

            if (ticketNum <= 0) {
                System.out.println("End of ticket sales...");
                break;
            }

            //Sleep for 50 ms, analog
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("window " + Thread.currentThread().getName() + " Sell a ticket"
                    + " Remaining votes=" + (--ticketNum));//1 - 0 - -1  - -2

        }
    }
}

3. Precautions and details

8, Thread deadlock

1. Basic introduction

For example:

package com.hspedu.syn;

/**
 * Simulate thread deadlock
 */
public class DeadLock_ {
    public static void main(String[] args) {
        //Simulate deadlock
        DeadLockDemo A = new DeadLockDemo(true);
        A.setName("A thread ");
        DeadLockDemo B = new DeadLockDemo(false);
        B.setName("B thread ");
        A.start();
        B.start();
    }
}


//thread 
class DeadLockDemo extends Thread {
    static Object o1 = new Object();// Ensure multithreading and share an object. Here, use static
    static Object o2 = new Object();
    boolean flag;

    public DeadLockDemo(boolean flag) {//constructor 
        this.flag = flag;
    }

    @Override
    public void run() {

        //The following is the analysis of business logic
        //1. If the flag is T, thread A will get / hold the o1 object lock first, and then try to get the o2 object lock
        //2. If thread A cannot get o2 object lock, it will be Blocked
        //3. If the flag is F, thread B will get / hold the o2 object lock first, and then try to get the o1 object lock
        //4. If thread B cannot get the o1 object lock, it will be Blocked
        if (flag) {
            synchronized (o1) {//Object mutex, the following is the synchronization code
                System.out.println(Thread.currentThread().getName() + " Enter 1");
                synchronized (o2) { // Here you get the monitoring right of li object
                    System.out.println(Thread.currentThread().getName() + " Enter 2");
                }
                
            }
        } else {
            synchronized (o2) {
                System.out.println(Thread.currentThread().getName() + " Enter 3");
                synchronized (o1) { // Here you get the monitoring right of li object
                    System.out.println(Thread.currentThread().getName() + " Enter 4");
                }
            }
        }
    }
}

9, Release lock

1. The following operation will release the lock

2. The following operation will not release the lock

I'm classmate Lu. I wish myself and you become stronger~

Topics: Java