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