4.26-4.27 multi thread learning notes
Multithreading
1. Threads are independent execution paths
2. A process contains threads, which may execute a process, and multiple threads are executing at the same time.
3. If multiple threads are opened in a process, the operation of threads is scheduled by the scheduler. The scheduler is closely related to the operating system, and the sequence cannot be interfered by human beings,
4. Each thread interacts in its own working memory. Improper memory control will cause inconsistent data.
5. In the real sense, multithreading is the simultaneous execution of multiple CPUs and multi-core, such as servers. The simulated multithreading is still single thread, because the call speed of cpu is fast.
Inherit Thread class
package cx.javathread; /** * @ClassName thread1 * Description Inheriting Thread class to implement Thread * Author CX * Date 2021/4/26 10:09 */ public class thread1 extends Thread{ @Override public void run() { //Override run method for (int i = 0; i < 20; i++) { System.out.println("This is the first inheritance thread class"+i); } } public static void main(String[] args) { thread1 t1=new thread1();//Instantiate thread object t1.start();//Start the thread through the start method for (int i = 0; i < 200; i++) { System.out.println("This is the main thread"+i); } } }
Implement Runnable interface
package cx.javathread; /** * @ClassName RunnableThread * Description TOOD * Author CX * Date 2021/4/26 10:13 */ public class RunnableThread implements Runnable{ @Override public void run() { //Override the run method of runnable for (int i = 0; i < 20; i++) { System.out.println("Here is runnable Threaded run method"+i); } } public static void main(String[] args) { RunnableThread r1=new RunnableThread(); Thread t1=new Thread(r1); t1.start(); for (int i = 0; i < 300; i++) { System.out.println("The main thread is here"+i); } } }
Multithreading through tortoise and rabbit race
package cx.javathread; /** * @ClassName Race * Description Simulated tortoise rabbit race * Author CX * Date 2021/4/26 10:45 */ public class Race implements Runnable{ public static String winner; @Override public void run() { for (int i = 0; i <=100; i++) { try { if(Thread.currentThread().getName().equals("rabbit")&&i%10==0){ Thread.sleep(1); } } catch (InterruptedException e) { e.printStackTrace(); } boolean flag=gameover(i); if(flag){ break; } System.out.println(Thread.currentThread().getName() + "----Run away" + i + "step"); } } //How to judge the end of the game public boolean gameover(int i){ if (winner != null) { return true; }if (i==100){ winner=Thread.currentThread().getName(); System.out.println("winner is"+winner); return true; } return false; } public static void main(String[] args) { Race race=new Race(); Thread t1=new Thread(race,"rabbit"); Thread t2=new Thread(race,"tortoise"); t1.start(); t2.start(); } }
Implement Callable interface
package cx.javathread; import java.util.concurrent.*; /** * @ClassName CallableThread * Description Implement Callable interface * Author CX * Date 2021/4/26 14:54 */ public class CallableThread implements Callable<Boolean>{ @Override public Boolean call() throws Exception { //Override the call method of Callable for (int i = 0; i < 20; i++) { System.out.println("Here is Callable Threaded call method"+i); } return true; } public static void main(String[] args) throws ExecutionException, InterruptedException { CallableThread call=new CallableThread();//Instantiate Callable object //Open the Callable thread and specify the number of threads nThreads ExecutorService ser= Executors.newFixedThreadPool(1); //Submit thread call Future<Boolean> r1= ser.submit(call); //Get results boolean b1=r1.get(); //Close thread ser.shutdownNow(); } }
Lamda expression
Functional interface:
If any interface has only one abstract method, it is a functional interface. For a functional interface, we can create the object of the interface through lamda expression.
Summary: 1 lamda expressions can be used only when the interface is an abstract functional interface
2. Remove the parentheses. When there is only one parameter, you can remove the parentheses ().
3. Remove the curly braces. When there is only one Java statement inside, you can remove the curly braces {}
package cx.javathread; /** * @ClassName JavaLamda * Description Implement lamda to simplify operation * Author CX * Date 2021/4/26 16:47 */ public class JavaLamda { public static void main(String[] args) { //lambda simplifies operations love l=new love() { @Override public void lambda(int i) { System.out.println("This is an anonymous inner class"+i); } }; l.lambda(520); //lamda expression love l2=(int a)->{ System.out.println("This is lamda Application of expression"+a); }; l2.lambda(521); //lamda simplifies one and removes the return type love l3=(a)->{ System.out.println("This is lamda Simplification of expression I"+a); }; l3.lambda(522); //lamda simplifies two and removes parentheses. When there is only one parameter, parentheses can be removed (). love l4=a->{ System.out.println("This is lamda Simplification of expression II"+a); }; l4.lambda(523); //lamda simplifies the three and removes the curly braces. When there is only one Java statement inside, the curly braces can be removed {}. love l5=a-> System.out.println("This is lamda Three simplifications of expressions"+a); l5.lambda(524); } interface love { public void lambda(int i); } }
Status of the thread
Thread termination
Stop or destroy methods are not recommended. It is recommended that threads stop normally or use flag bits.
Thread hibernation
Sleep (time) specifies the number of milliseconds that the current thread is blocked;
There is an exception InterruptedException in sleep;
After the sleep time reaches, the thread enters the ready state
sleep can simulate network delay, countdown, etc;
Each object has a lock, and sleep will not release the lock;
It can amplify the occurrence of the problem
Thread comity
Thread comity, which allows the currently executing thread to pause without blocking
Change the thread from running state to ready state
Let the cpu reschedule, comity is not necessarily successful, depending on the cpu mood
package cx.javathread; /** * @ClassName ThreadJoin * Description TOOD * Author CX * Date 2021/4/26 19:16 */ public class ThreadJoin implements Runnable{ @Override public void run() { for (int i = 0; i < 400; i++) { System.out.println("thread vip coming"+i); } } public static void main(String[] args) throws InterruptedException { ThreadJoin j=new ThreadJoin(); Thread t=new Thread(j); t.start(); for (int i = 0; i < 300; i++) { if (i==200){ t.join(); } System.out.println("main"+i); } } }
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 higher the priority of a thread is, the higher the priority is, the greater the weight will be.
The priority of threads is expressed in numbers, ranging from 1 to 10
Thread.MIN_PRIORTY=1;
Thread.MAX_PRIORTY=10;
Thread.NORM_PRIORTY=5;
You can the priority of this table thread in the following ways
getPrority().setPriority(int XXX);
package cx.javathread; /** * @ClassName ThtreadProity * Description Test thread priority * Author CX * Date 2021/4/26 19:33 */ public class ThtreadProity { public static void main(String[] args) { MyProity m=new MyProity(); Thread t1=new Thread(m); Thread t2=new Thread(m); Thread t3=new Thread(m); Thread t4=new Thread(m); t1.start(); t2.setPriority(1); t2.start(); t3.setPriority(5); t3.start(); t4.setPriority(10); t4.start(); } } class MyProity implements Runnable{ @Override public void run() { System.out.println(Thread.currentThread().getName()+"---"+Thread.currentThread().getPriority()); } }
Daemon thread
Threads are divided into user threads and daemon threads
The virtual machine must ensure that the user thread has completed execution
The virtual machine does not have to wait for the daemon thread to finish executing
package cx.javathread; /** * @ClassName ShouhuThread * Description Test daemon thread * Author CX * Date 2021/4/26 19:44 */ public class ShouhuThread { public static void main(String[] args) { God god=new God(); you you=new you(); Thread t1=new Thread(god); t1.setDaemon(true);//Set as daemon thread. The default is false. If false, it is the user thread, and if true, it is the daemon thread t1.start(); new Thread(you).start();//User thread start } } class God implements Runnable{ @Override public void run() { while (true){ System.out.println("Guard you"); } } } //User thread class you implements Runnable{ @Override public void run() { for (int i = 0; i < 30; i++) { System.out.println("Live happily"); } System.out.println("goodbye!"); } }
Thread synchronization mechanism:
ArrayList is unsafe. It may be that two threads operate on one data at the same time, and it will be overwritten, so the number will be reduced
The synchronized lock method defaults to the object of the lock
package cx.javathread; /** * @ClassName UnsafeBuyTicket * Description Unsafe ticket buying, someone gets the same ticket or negative number. Lock the run method with synchronized * Author CX * Date 2021/4/26 20:03 */ public class UnsafeBuyTicket { public static void main(String[] args) { BuyTicket buy=new BuyTicket(); new Thread(buy,"Xiao Ming").start(); new Thread(buy,"Xiao Hong").start(); new Thread(buy,"Xiaohua").start(); } } class BuyTicket implements Runnable{ private int ticketNums = 10; boolean flag=true; @Override public void run() { while (flag){ buy(); } } public synchronized void buy(){ //Locking allows threads to queue up. The thread that gets the lock runs first, and the thread that doesn't get the lock waits //Judge whether there are tickets if (ticketNums<=0){ flag=false; return; } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } //Output ticket buyer System.out.println(Thread.currentThread().getName()+"Get"+ticketNums--); } }
Synchronized (object) {} synchronized synchronizes the amount of block lock changes and the objects that need to be added, deleted and modified
package cx.javathread; import java.util.ArrayList; import java.util.List; /** * @ClassName UnsafeList * Description Lock the objects of the List with synchronized synchronization blocks. * Author CX * Date 2021/4/27 9:16 */ public class UnsafeList { public static void main(String[] args) { List l=new ArrayList(); for (int i = 0; i < 1000; i++) { new Thread(()->{ synchronized (l) { l.add(Thread.currentThread().getName()); } }).start(); } try { Thread.sleep(100); } catch (InterruptedException e) { } System.out.println(l.size()); } }
deadlock
Multithreads occupy some shared resources and wait for the resources occupied by other threads to run. As a result, two or more threads are waiting for each other to release resources and stop execution. Deadlock may occur when a synchronization block has locks of more than two objects at the same time.
Case:
package cx.javathread; /** * @ClassName DeadLock * Description Deadlock: multiple threads hold each other's required resources, and then form a deadlock * Author CX * Date 2021/4/27 9:31 */ public class DeadLock { public static void main(String[] args) { Makeup g1=new Makeup(0,"Xiao Ming"); Makeup g2=new Makeup(1,"Xiao Hong"); g1.start(); g2.start(); } } class Lipatick{ } class mirror{ } class Makeup extends Thread{ //Only one resource is needed, and only one is guaranteed through static static Lipatick lipatick=new Lipatick(); static mirror m=new mirror(); int choice;//choice String girlname;//People who use cosmetics Makeup( int choice, String girlname){ this.choice=choice; this.girlname=getName(); } @Override public void run() { //Make up try { makeup(); } catch (InterruptedException e) { e.printStackTrace(); } } //Hold each other's locks and need to get each other's locks public void makeup()throws InterruptedException{ if (choice==0){ synchronized (lipatick){ System.out.println(this.girlname+"Get lipstick lock"); Thread.sleep(1000);//After a second, I want to get the lock of the mirror synchronized (m){ System.out.println(this.girlname+"Get the lock of the mirror"); } } }else { synchronized (m){ System.out.println(this.girlname+"Get the lock of the mirror"); Thread.sleep(2000); synchronized (lipatick){ System.out.println(this.girlname+"Get lipstick lock"); } } } } }
Modification method: take out the code lock in the synchronization block to avoid two or more locks in the synchronization code block.
package cx.javathread; /** * @ClassName DeadLock * Description Deadlock: multiple threads hold each other's required resources, and then form a deadlock * Author CX * Date 2021/4/27 9:31 */ public class DeadLock { public static void main(String[] args) { Makeup g1=new Makeup(0,"Xiao Ming"); Makeup g2=new Makeup(1,"Xiao Hong"); g1.start(); g2.start(); } } class Lipatick{ } class mirror{ } class Makeup extends Thread{ //Only one resource is needed, and only one is guaranteed through static static Lipatick lipatick=new Lipatick(); static mirror m=new mirror(); int choice;//choice String girlname;//People who use cosmetics Makeup( int choice, String girlname){ this.choice=choice; this.girlname=getName(); } @Override public void run() { //Make up try { makeup(); } catch (InterruptedException e) { e.printStackTrace(); } } //Hold each other's locks and need to get each other's locks public void makeup()throws InterruptedException{ if (choice==0){ synchronized (lipatick){ System.out.println(this.girlname+"Get lipstick lock"); Thread.sleep(1000);//After a second, I want to get the lock of the mirror } synchronized (m){ System.out.println(this.girlname+"Get the lock of the mirror"); } }else { synchronized (m){ System.out.println(this.girlname+"Get the lock of the mirror"); Thread.sleep(2000); } synchronized (lipatick){ System.out.println(this.girlname+"Get lipstick lock"); } } } }
Lock lock
ReentrantLock: repeatable lock
package cx.javathread; import java.util.concurrent.locks.ReentrantLock; /** * @ClassName JavaLock * Description TOOD * Author CX * Date 2021/4/27 10:02 */ public class JavaLock implements Runnable{ public static void main(String[] args) { JavaLock j1=new JavaLock(); JavaLock j2=new JavaLock(); Thread t1=new Thread(j1,"t1"); Thread t2=new Thread(j1,"t2"); t1.start(); t2.start(); } int tick=10; private final ReentrantLock lock=new ReentrantLock();//Define Lock lock @Override public void run() { while (true){ try { lock.lock();//Lock if(tick>0) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(tick--); }else { break; } }finally { lock.unlock();//Release lock } } } }
Comparison between synchronized and Lock
Thread collaboration:
Pipe program method
/** * @ClassName TestPC * Description Test the producer consumer model and solve it with buffer: pipe process method * Author CX * Date 2021/4/27 10:21 */ public class TestPC { public static void main(String[] args) { SynContainer container = new SynContainer() ; new Productor(container).start(); new Consumer(container).start(); } } //producer class Productor extends Thread{ SynContainer container; public Productor(SynContainer container){ this.container=container; } @Override public void run() { for (int i = 0; i < 100; i++) { container.push(new Chicken(i)); System.out.println("Produced"+i+"Chicken"); } } } //consumer class Consumer extends Thread{ SynContainer container; public Consumer(SynContainer container){ this.container=container; } @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println("Consumption-->"+container.pop().id+"Chicken"); } } } //product class Chicken{ int id; public Chicken(int id) { this.id = id; } } class SynContainer{ Chicken[] chickens=new Chicken[10];//container int count=0;//Counter //Put in the product public synchronized void push(Chicken chicken){ if (count==chickens.length){ //Inform consumers to consume and producers to wait try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //If it is not full, we need to throw in the product chickens[count]=chicken; count++; //Inform consumers of consumption this.notify(); } public synchronized Chicken pop(){ if(count==0){ //Wait for producers to produce and consumers to wait try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } count--; Chicken chicken=chickens[count]; //Inform the producer of the production this.notify(); return chicken; } }
Signal lamp method:
/** * @ClassName TestPC2 * Description Signal lamp method * Author CX * Date 2021/4/27 10:58 */ public class TestPC2 { public static void main(String[] args) { TV tv=new TV(); new Player(tv).start(); new Watcher(tv).start(); } } //Producer actor class Player extends Thread{ TV tv; public Player(TV tv){ this.tv=tv; } @Override public void run() { for (int i = 0; i < 20; i++) { if(i%2==0){ this.tv.play("Happy base camp"); }else { this.tv.play("Tiktok"); } } } } //Consumer audience class Watcher extends Thread{ TV tv; public Watcher(TV tv){ this.tv=tv; } @Override public void run() { for (int i = 0; i < 20; i++) { this.tv.watch(); } } } //Products -- programs class TV{ //The actor performs and the audience waits for T //The audience watched and the actors waited for F String voice;//A performance boolean flag=true; //Flag bit //perform public synchronized void play(String voice){ if(!flag){ try { this.wait();//Actor waiting } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("The actors performed:"+voice); this.notifyAll();//Notification wake-up this.voice=voice; this.flag=!this.flag; } public synchronized void watch(){ if (flag) { try { this.wait();//Audience waiting } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("Watched"+voice); this.notifyAll();//Wake up the performer this.flag=!this.flag; } }
Thread pool
package cx.javathread; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * @ClassName TestPool * Description Test thread pool to implement Runnable interface * Author CX * Date 2021/4/27 11:13 */ public class TestPool { public static void main(String[] args) { ExecutorService service= Executors.newFixedThreadPool(10);//Create a thread pool. The newFixedThreadPool (parameter) parameter is the size of the thread pool service.execute(new MyThread()); service.execute(new MyThread()); service.execute(new MyThread()); service.execute(new MyThread()); //Close connection service.shutdownNow(); } } class MyThread implements Runnable{ @Override public void run() { System.out.println(Thread.currentThread().getName()); } }