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