Summary of multi thread knowledge points

Keywords: Java

Content navigation: This paper is divided into four parts: 1. Multi thread implementation; 2. Thread safety; 3. Inter thread communication; 4. Producer consumer model

The first part is the realization of multithreading. There are two ways to realize multithreading in java

I. customize a Class A to inherit Thread class

1 public class ThreadA extends Thread {
2     public void run(){
3        
4         }
5     }
6 
7 }

At this time, Thread a is a Thread class. Rewrite the run method in the Thread class in Thread a

Call as follows

ThreadA A = new ThreadA();
A.start();

 

 

2. Define a class B to implement the Runable interface

1 public class ThreadB implements Runnable {
2     public void run() {
3        
4     }
5 }

 

At this time, ThreadB is not a Thread class. Rewrite the run method in the Thread class in ThreadB

ThreadB b = new ThreadB();
Thread t1 = new Thread(b);
t1.start();

 

When initializing the Thread, you need to pass in the object b of the implementation class of the Runnable interface as a parameter

 

 

 

The second part is thread safety

Scenarios of thread safety problems:

 1 public class SaleTickets implements Runnable {
 2 
 3     private int num = 100;   //100 train tickets. This is a shared resource
 4 
 5     //buy100 Zhang train ticket
 6     public void run() {
 7         for (int i = 0; i < num; i++) {
 8             if (id > 0) {
 9                 System.out.println(Thread.currentThread().getName() + "Bought the number" + num + "Train ticket");
10                 num--;
11                 try {
12                     Thread.sleep(500);
13                 } catch (InterruptedException e) {
14                 }
15             }
16         }
17     }
18 }

 

SaleTickets st=new SaleTickets ();
Thread tA=new Thread(st);    //user A
Thread tB=new Thread(st);    //user B

tA.setName("user A thread");
tB.setName("user B thread");

tA.start();
tB.start();
            

 

When entering 12306 to purchase train tickets, in order to solve the problem of multiple people robbing tickets at the same time, it is necessary to use multiple threads to increase the system efficiency. If there are 100 tickets in total, user A and user B will buy tickets at the same time. If it is A single thread, each time when the user buys A ticket, it will first print which ticket the user bought, and then the total number of tickets num minus 1.

However, due to multithreading, one feature of multithreading is that the execution sequence of threads is allocated by cpu, so the execution sequence is uncertain. If user a executes line 10 of SaleTickets method, it will print out the train ticket with No. 100 purchased by user A. at this time, user B will also start to execute SaleTickets method, and user B will also print out the train ticket purchased by user B. Train ticket No. 100

This result is not reasonable, so it causes thread safety problems

There are two ways to solve thread safety problems

1. Synchronization code block

 1 public class SaleTickets implements Runnable {
 2 
 3     private int num = 100;   //100 train tickets. This is a shared resource
 4 
 5     //Buy 100 train tickets
 6     public void run() {
 7         for (int i = 0; i < num; i++) {
 8             synchronized (this){
 9                 if (num > 0) {
10                 System.out.println(Thread.currentThread().getName() + "Bought the number" + num + "Train ticket");
11                 num--;
12                 try {
13                     Thread.sleep(500);
14                 } catch (InterruptedException e) {
15                 }
16              }
17              }   
18         }
19     }
20 }            

 

2. Synchronization method

 1 public class SaleTickets implements Runnable {
 2 
 3     private int num = 100;   //100 train tickets. This is a shared resource
 4 
 5     public synchronized  void saleOne(){
 6         if (num > 0) {
 7             System.out.println(Thread.currentThread().getName() + "Bought the number" + num + "Train ticket");
 8             num--;
 9             try {
10                 Thread.sleep(500);
11             } catch (InterruptedException e) {
12             }
13         }
14     }
15 
16     //Buy 100 train tickets
17     public void run() {
18         for (int i = 0; i < 10; i++) {
19             saleOne();
20         }
21     }
22 }

 

At this time, the synchronized lock in the synchronization method defaults to this

 

 

 

The third part is inter thread communication

The communication mechanism between threads is wait wake mechanism. The premise of multiple threads communication is to share the same lock

wait (long timeout) the current thread releases the lock and waits for timeout milliseconds

notify wakes up a thread holding the same lock

1. Define a static object object as a lock for inter thread communication

1 public class MyLock {
2     public static Object obj = new Object();
3 }

 

2. Define thread A

 1 //Define a thread class output 1
 2 public class ThreadA extends Thread {
 3 
 4     public void run(){
 5         for(int j=0;j<10;j++){
 6             synchronized (MyLock.obj) {
 7                 System.out.println(1);
 8                 MyLock.obj.notify();
 9                 try {
10                     MyLock.obj.wait();
11                 } catch (InterruptedException e) {
12                     e.printStackTrace();
13                 }
14             }
15         }
16     }
17 
18 }

 

3. Define thread B

 1 //Define a thread class output 2
 2 public class ThreadB extends Thread {
 3 
 4     public void run(){
 5         for(int j=0;j<10;j++){
 6             synchronized (MyLock.obj) {
 7                 System.out.println(2);
 8                 MyLock.obj.notify();
 9                 try {
10                     MyLock.obj.wait();
11                 } catch (InterruptedException e) {
12                     e.printStackTrace();
13                 }
14             }
15         }
16     }
17 
18 }

 

4. Define main function execution thread A and thread B

1 public class TestThreadForSignal {
2     public static void main(String[] args){
3         new ThreadA().start();
4         new ThreadB().start();
5     }
6 }

 

Execution result: print 1 and 2 alternately

Execution principle: first execute thread A, which will be locked by synchronized code block, print 1, and then wake up thread B sharing MyLock.obj lock, and then thread A will enter wait and release the lock. Then execute thread B, which will be locked by synchronized code block, print 2, wake up thread A sharing MyLock.obj lock, and then thread B will enter the wait and release the lock. Next, continue to execute thread A, and repeat

 

 

 

The fourth part is the producer consumer model

The producer consumer mode can be well realized by using the inter thread communication

Because this code is very similar to the above thread communication code, the blogger here doesn't intend to continue the code, and makes a brief description with words

Thread A (farmer) puts apples in the basket. If the basket is full (number of apples = 10), thread A wait s. If the basket is not full (number of apples < 10), put apples in the basket and tell B (child) notify to wake up

Thread B (child) takes apples from the basket to eat. If the basket is empty (number of apples = 0), thread B wait. If there are apples in the basket (number of apples > 0), take apples from the basket to eat. At the same time, tell A (farmer) notify to wake up

In this scenario, thread A (farmer) is the producer and thread B (child) is the consumer

Posted by SupaMonkey on Fri, 22 Nov 2019 01:49:28 -0800