Multithreading review

Posted by Infinitive on Fri, 17 Dec 2021 07:09:35 +0100

title: multithreading review

date: 2020/10/17

1. Thread life cycle and status

Newborn, ready, running, blocked, dead

2. sleep,wait,join,yield

3. Understanding of thread safety

Example 1: if there are 10 tickets and three people buy them at the same time, because there is no thread synchronization, they may buy the same ticket. When there is only the last ticket, two or even three people may grab the last ticket, and there may be negative tickets

Example 2: your bank account has 100 yuan. You withdraw money with your daughter-in-law. One person withdraws 50 yuan and the other withdraws 100 yuan, which may cause the bank to lose money

Example 3: when adding values to the list set, two threads add values to the same location at the same time, which will reduce the number of elements

Solution: synchronized (queue + lock) keyword

1. Synchronization method

2. Synchronization block: synchronized (obj) {}. The monitored object obj is the object that needs to be added, deleted, modified and queried

Principle: synchronized methods control access to "objects". Each object corresponds to a lock. Each synchronized method must obtain the lock of the object calling the method before it can be executed. Otherwise, the thread will block. Once the method is executed, it will monopolize the lock until the method returns. The lock will not be released until the method returns. The blocked thread can obtain the lock and continue to execute

4. Thread and Runnable

5. Talk about your understanding of daemon thread

Threads are divided into user threads and daemon threads

The virtual machine must ensure that user execution is complete

After the user thread is executed, the virtual machine will stop immediately without waiting for the daemon thread to execute

Such as recording operation logs in the background, monitoring memory, garbage collection and so on

thread.setDaemon(true); //The default value is false, which means user threads. Normal threads are user threads

6. Principle and usage scenario of thread local

7. How to avoid thread local memory leakage

8. Concurrent, parallel and serial

9. Three characteristics of concurrency

10. Why use thread pool? Parameter explanation

11. Principle of thread pool and thread reuse

12. There are two ways to create threads

12.1 implementation of Thread class

//Thread creation method 1: inherit the thread class, rewrite the run() method, and call start to start the thread
public class TsetThread1 extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            System.out.println("I'm looking at the code---"+i);
        }

    }

    public static void main(String[] args) {
        //main thread

        //1. Create a thread object
        TsetThread1 tsetThread1 = new TsetThread1();

        //2. Call the start() method to start the thread
        tsetThread1.start();


        for (int i = 0; i < 200; i++) {
            System.out.println("I'm learning multithreading--"+i);
        }
    }
}

12.2 implementation of Runnable

//Thread creation mode 2: implement the Runnable interface, rewrite the run() method, and call start to start the thread
public class TsetThread2 implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            System.out.println("I'm looking at the code---"+i);
        }

    }
    public static void main(String[] args) {
        //main thread

        //1. Create a thread object
        TsetThread2 tsetThread2 = new TsetThread2();
        //Create a thread object and start the thread agent through the thread object
        Thread thread = new Thread(tsetThread2);
        thread.start();


        for (int i = 0; i < 200; i++) {
            System.out.println("I'm learning multithreading--"+i);
        }
    }
}

13. Lambda expression

  • lambda expressions can only be reduced to one line if there is only one line of code. If there are multiple lines, they are wrapped in code blocks
  • The premise is that the interface is functional (there is only one method)
  • You can also remove parameter types from multiple parameters. If you want to remove them, you must remove them all and add parentheses
public class TsetLambda {


    public static void main(String[] args) {
        Ilove love = null;

        love = (a, b, c) -> {
            System.out.println("I Love you-->"+a+b+c);
        };

        love.love(1,2,3);
    }

}

interface Ilove{
    void love(int a,int b,int c);
}

Simplify the process; Common interface implementation class - > static inner class - > local inner class - > anonymous inner class - > lambda expression

14. sleep

thread.sleep(100)  //Stop for 100ms
  • sleep specifies the number of milliseconds the current thread is blocking
  • Exception InterruptedException in sleep
  • When the sleep time reaches, the thread enters the ready state
  • sleep can simulate network delay, countdown, etc
  • Each object has a lock, and sleep does not release the lock

15. yield

Comity thread, which suspends the currently executing thread without blocking

Transition a thread from a running state to a ready state

Let the CPU reschedule. Comity is not necessarily successful. It depends on the CPU mood

public class TsetYield{
    public static void main(String[] args) {
        MyYield myYield = new MyYield();

        new Thread(myYield,"a").start();
        new Thread(myYield,"b").start();
    }
}

class MyYield implements Runnable {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"Thread starts execution");
        Thread.yield();//Comity
        System.out.println(Thread.currentThread().getName()+"Thread stop execution");
    }
}

16. Join

join merge threads. After this thread completes execution, execute other threads. Other threads are blocked

public class TestJoin implements Runnable{

    @Override
    public void run() {

        for (int i = 0; i < 1000; i++) {
            System.out.println("thread  vip coming"+i);
        }
    }
    public static void main(String[] args) throws InterruptedException {
        //Start the thread of TestJoin
        TestJoin testJoin = new TestJoin();
        Thread thread = new Thread(testJoin);
        thread.start();

        //Start main thread
        for (int i = 0; i < 500; i++) {
            if(i==200){
                thread.join();//Jump in line
            }
            System.out.println("main"+i);
        }
    }
}

17. Thread priority

Java provides a thread scheduler to monitor all threads that enter the ready state after startup. The thread scheduler determines which thread should be scheduled to execute according to priority

The priority of threads is expressed in numbers, ranging from 1 to 10

Thread.MIN_PRIOPRITY = 1;

Thread.MAX_PRIOPRITY = 10;

Thread.NORM_PRIOPRITY = 5;

Change or get priority in the following ways

getPriority().setPriority(int ×××)

18. Examples of thread insecurity

18.1 unsafe ticket purchase

public class UnsafeBuyTicket {
    public static void main(String[] args) {
        BuyTicket buyTicket = new BuyTicket();

        Thread thread1 = new Thread(buyTicket,"I");
        Thread thread2 = new Thread(buyTicket,"you");
        Thread thread3 = new Thread(buyTicket,"cattle");

        thread1.start();
        thread2.start();
        thread3.start();
    }
}
class BuyTicket implements Runnable{

    //Number of tickets
    private int ticketNums = 10;
    //External stop mode
    boolean flag = true;

    @Override
    public void run() {
        //Buy a ticket
        while(flag){
            try {
                buy();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    //The ticket purchase method, synchronized synchronization method, locks this
    private synchronized void buy() throws InterruptedException {
        //Judge whether there are tickets
        if (ticketNums<=0) {
            flag = false;
            return;
        }else {
            //Analog delay
            Thread.sleep(100);

            System.out.println(Thread.currentThread().getName() + "Get" + ticketNums--);
        }
        }
    }

18.2 unsafe withdrawal

public class UnsafeBank {

    public static void main(String[] args) {
        Account account = new Account(100, "Marriage fund");
        Drawing you = new Drawing(account, 50, "you");
        Drawing girlfriend = new Drawing(account, 100, "girlfriend");

        you.start();
        girlfriend.start();

    }
}
//account
class Account{
    int money; //balance
    String name; //Card name


    public Account(int money, String name) {
        this.money = money;
        this.name = name;
    }
}

//bank
class Drawing extends Thread{
    Account account;//account
    int drawingMoney;//How much did you withdraw
    int nowMoney; //The money in your hand

    public Drawing(Account account,int drawingMoney,String name){
        super(name);
        this.account = account;
        this.drawingMoney = drawingMoney;

    }
    //Withdraw money
    @Override
    public  void run() {

        //The object of the lock is the quantity of change and needs to be added, deleted and modified
        synchronized (account){
            //Judge whether there is money
            if(account.money-drawingMoney<0){
                System.out.println(Thread.currentThread().getName()+"There's not enough money to withdraw!");
                return;
            }

            //Analog delay
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //Card balance
            account.money = account.money-drawingMoney;
            //The money in your hand
            nowMoney = nowMoney + drawingMoney;

            System.out.println(account.name+"The balance is:"+account.money);
            System.out.println(Thread.currentThread().getName()+"Money in hand:"+nowMoney);
        }

    }
}

18.3 unsafe assembly

public class UnsafeList {
    public static void main(String[] args) throws InterruptedException {
        ArrayList<String> list = new ArrayList<>();
        for (int i = 0; i < 10000; i++) {
            new Thread(()->{
                synchronized (list){
                    list.add(Thread.currentThread().getName());
                }
            }).start();
        }
        Thread.sleep(3000);

        System.out.println(list.size());
    }
}

19. Lock

19.1 deadlock

Multiple threads occupy some shared resources and wait for the resources occupied by other threads to proceed. As a result, two or more threads are waiting for each other to release resources and stop execution. When a synchronization block has "locks of more than two objects" at the same time, the problem of "deadlock" may occur

19.2 Lock lock

private final ReentrantLock lock = new ReentranLock();
try{
  lock.lock();//Lock
    ...
}finally{
    //Unlock
    lock.unlock();
}

20. wait()

Function: indicates that the thread waits until other threads notify it. Unlike sleep, it will release the lock

Wait (long timeout): Specifies the number of milliseconds to wait

21. Thread pool

public class TestPool {

    public static void main(String[] args) {
        //Create service, create thread pool
        //The newFixedThreadPool parameter is the size of the thread pool
        ExecutorService service = Executors.newFixedThreadPool(10);

        //implement
        service.execute(new MyThread());
        service.execute(new MyThread());
        service.execute(new MyThread());
        service.execute(new MyThread());

        //Close connection
        service.shutdown();
    }
}

class MyThread implements Runnable{

    @Override
    public void run() {
            System.out.println(Thread.currentThread().getName());
        }
    }

ExecutorService: real thread pool interface

void execute(Runnable command): executes a task / command without a return value. It is generally used to execute Runnable

void shutdown(): closes the connection pool

Executors: tool class and engineering class of thread pool, which are used to create and return different thread pools

Topics: Java Interview