##Write a blog for the first time and share your study notes with you
##The video link points to the teaching video of Madness (for free)
##If there are mistakes, please criticize and correct them
##If infringement is involved, please contact me to delete it
Multithreading
The thread is not necessarily executed immediately after it is started, and is scheduled by the CPU
1. Multi thread creation method
1.1 Thread creation method 1: inherit the Thread class, rewrite the Thread body of the run method, and call start();
/* The thread is not necessarily executed immediately after it is started, and the cpu arranges the scheduling */ //Thread creation method 1: inherit the thread class, rewrite the thread body of the run method, and call start(); //Inherit Thread class public class TestThread1 extends Thread{ //Override the run method thread body public void run() { for (int i = 0; i < 20; i++) { System.out.println("Jay " + i); } } public static void main(String[] args) { //Create a thread object TestThread1 testThread1 = new TestThread1(); //Call the start() method to start the thread testThread1.start(); for (int i = 0; i < 20; i++) { System.out.println("Soul " + i); } } }
package Jay; import org.apache.commons.io.FileUtils; import java.io.File; import java.io.IOException; import java.net.URL; /* Practice Thread to realize multi-threaded synchronous downloading of pictures */ public class TestThread2 extends Thread{ private String url; private String name; public TestThread2(String url, String name){ this.url = url; this.name = name; } //Thread executor for downloading pictures public void run(){ WebDownloader webDownloader = new WebDownloader(); webDownloader.downloader(url, name); System.out.println(name + " File downloaded successfully"); } public static void main(String[] args) { TestThread2 t1 = new TestThread2("https://cdn.jsdelivr.net/gh/filess/img17@main/2021/05/07/1620371242789-b286c6f7-a06c-48c7-a53b-3a86d18cea97.png", "p1.png"); TestThread2 t2 = new TestThread2("https://cdn.jsdelivr.net/gh/filess/img16@main/2021/05/07/1620377761880-1d4715d4-482c-4d52-a5aa-210a1a354c77.png", "p2.png"); TestThread2 t3 = new TestThread2("https://cdn.jsdelivr.net/gh/filess/img8@main/2021/05/07/1620377156603-8b53ee53-8de0-4f81-b667-3df6ce555064.png", "p3.png"); t1.start(); t2.start(); t3.start(); } } //Downloader class WebDownloader{ public void downloader(String url, String name){ try { FileUtils.copyURLToFile(new URL(url), new File(name)); } catch (IOException e) { e.printStackTrace(); System.out.println("IO Abnormal, downloader There was a problem downloading"); } } }
1.2 create thread method 2: implement the runnable interface, rewrite the run method, and the execution thread needs to drop into the runnable interface implementation class and call the start method
//Create thread method 2: implement the runnable interface. Rewrite the run method. The execution thread needs to drop into the runnable interface implementation class and call the start method public class TestThread3 implements Runnable{ //Override the run method thread body public void run() { for (int i = 0; i < 20; i++) { System.out.println("Jay " + i); } } public static void main(String[] args) { //Create an implementation class object for the runnable interface TestThread3 testThread3 = new TestThread3(); //Create a thread object and start my thread (proxy) through the thread object new Thread(testThread3).start(); for (int i = 0; i < 20; i++) { System.out.println("Soul " + i); } } }
When multiple threads operate on the same object at the same time, the thread is unsafe and the data is disordered
//When multiple threads operate on the same object at the same time, the thread is unsafe and the data is disordered //Example of buying a train ticket public class TestThread4 implements Runnable{ private int ticketNums = 10; public void run(){ while (true){ if (ticketNums <= 0){ break; } /*try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); }*/ System.out.println(Thread.currentThread().getName() + "-->Got the second" + ticketNums-- + "ticket"); } } public static void main(String[] args) { TestThread4 ticket = new TestThread4(); new Thread(ticket, "Xiao Ming").start(); new Thread(ticket, "Xiao Hong").start(); new Thread(ticket, "Xiao Huang").start(); } }
Tortoise and rabbit race
import kotlin.reflect.jvm.internal.impl.descriptors.Visibilities; //Simulated tortoise rabbit race public class Race implements Runnable{ private static String winner; @Override public void run() { for (int i = 1; i <= 100; i++) { if (Thread.currentThread().getName().equals("rabbit") && i % 60 == 0) { try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } if (gameOver(i)) break; System.out.println(Thread.currentThread().getName() + "-->Run away" + i + "step"); } } //Judge whether to complete the game private boolean gameOver (int step){ if (winner != null){ return true; } if (step >= 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(); new Thread(race, "rabbit").start(); new Thread(race, "tortoise").start(); } }
1.3 thread creation method 3: implement the callable interface
import org.apache.commons.io.FileUtils; import java.io.File; import java.io.IOException; import java.net.URL; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; //Thread creation mode 3: implement the callable interface /* callable Benefits of 1,You can define the return value 2,Exceptions can be thrown */ public class TestCallable implements Callable<Boolean> { private String url; private String name; public TestCallable(String url, String name){ this.url = url; this.name = name; } //Thread executor for downloading pictures public Boolean call(){ WebDownloader webDownloader = new WebDownloader(); webDownloader.downloader(url, name); System.out.println(name + " File downloaded successfully"); return true; } public static void main(String[] args) { TestCallable t1 = new TestCallable("https://cdn.jsdelivr.net/gh/filess/img17@main/2021/05/07/1620371242789-b286c6f7-a06c-48c7-a53b-3a86d18cea97.png", "p1.png"); TestCallable t2 = new TestCallable("https://cdn.jsdelivr.net/gh/filess/img16@main/2021/05/07/1620377761880-1d4715d4-482c-4d52-a5aa-210a1a354c77.png", "p2.png"); TestCallable t3 = new TestCallable("https://cdn.jsdelivr.net/gh/filess/img8@main/2021/05/07/1620377156603-8b53ee53-8de0-4f81-b667-3df6ce555064.png", "p3.png"); //Create execution service: ExecutorService ser = Executors.newFixedThreadPool(3); //Submit for execution Future<Boolean> r1 = ser.submit(t1); Future<Boolean> r2 = ser.submit(t2); Future<Boolean> r3 = ser.submit(t3); //Shut down service ser.shutdownNow(); } } //Downloader class WebDownloader{ public void downloader(String url, String name){ try { FileUtils.copyURLToFile(new URL(url), new File(name)); } catch (IOException e) { e.printStackTrace(); System.out.println("IO Abnormal, downloader There was a problem downloading"); } } }
2. Static proxy mode
package Jay; /* Static proxy: 1,Both real objects and proxy objects implement an interface 2,The proxy object needs a proxy role */ public class StaticProxy{ public static void main(String[] args) { new MarryCompany(new you()).happyMarry(); } } interface Marry{ public void happyMarry(); } //Real character marriage class you implements Marry{ @Override public void happyMarry() { System.out.println("Yuanbao is married"); } } //Wedding company agent class MarryCompany implements Marry{ private Marry target; public MarryCompany(Marry target) { this.target = target; } @Override public void happyMarry() { berfore(); this.target.happyMarry();//This is the real object after(); } private void after() { System.out.println("Closing payment"); } private void berfore() { System.out.println("Layout site"); } }
3. Lamda expression
3.1 why lamda representation
- Avoid too many anonymous inner class definitions - Make the code look concise, remove meaningless code, and leave only the core logic - Its essence belongs to the concept of functional programming
3.2 definition of functional interface
- Any interface that contains only one abstract method is a functional interface - For functional interfaces, we can lamda Expression to create an object of the interface
package thread.lamda; /* Derivation of lamda expression */ public class TestLamda01 { //3. Static internal class static class Like2 implements ILike{ @Override public void lamda() { System.out.println("I like lamda2!"); } } public static void main(String[] args) { ILike like = new Like(); like.lamda(); like = new Like2(); like.lamda(); //4. Local internal class class Like3 implements ILike{ @Override public void lamda() { System.out.println("I like lamda3!"); } } like = new Like3(); like.lamda(); //5. Anonymous inner class. There is no class name. You must use the interface or parent class like = new ILike() { @Override public void lamda() { System.out.println("I like lamda4!"); } }; like.lamda(); //6. Simplify with lamda like = ()->{ System.out.println("I like lamda5!"); }; like.lamda(); } } //1. Define a functional interface interface ILike{ void lamda(); } //2. Implementation class class Like implements ILike{ @Override public void lamda() { System.out.println("I like lamda!"); } }
package thread.lamda; public class TestLamda02 { //Static inner class static class love2 implements ILove{ @Override public void love(int a) { System.out.println("I love" + a); } } public static void main(String[] args) { //Common class implementation ILove love = new love(); love.love(1); //Static inner class implementation love = new love2(); love.love(2); //Local inner class class love3 implements ILove{ @Override public void love(int a) { System.out.println("I love" + a); } } new love3().love(77); //Anonymous Inner Class love = new ILove() { @Override public void love(int a) { System.out.println("I love" + a); } }; love.love(3); //lamda simplification love = (int a)->{ System.out.println("I love" + a); }; love.love(4); } } interface ILove{ void love(int a); } class love implements ILove{ @Override public void love(int a) { System.out.println("I love" + a); } }
3.3 simplified form of lamda
//Simplified form 1 love = (a) -> { System.out.println("I love" + a); }; //Simplified form 2 (parameter < = 1) love = a -> { System.out.println("I love" + a); }; //Simplified form 3 (only one line of code) love = a -> System.out.println("I love" + a);
4. Thread status and method
Once a thread enters a dead state, it cannot be started again
4.1 five states
* Create status( new) * Ready status( start) * running state * Blocking state( sleep,wait) * Death state
4.2 threading method
4.3 stopping threads
- It is recommended that the thread stop itself (dead loop is not recommended) - It is recommended to use a flag bit to terminate the variable (when flag= false,Terminate the thread) - Do not use stop perhaps destroy Etc. outdated or JDK Method not recommended
package thread.methods; //Test stop public class TestStop implements Runnable{ //1. Set a flag bit private boolean flag = true; @Override public void run() { int i = 0; while (flag){ System.out.println("run ....... Thread" + i++); } } //2. Set a public method to stop the thread and convert the flag bit public void stop(){ this.flag = false; } public static void main(String[] args) { TestStop testStop = new TestStop(); new Thread(testStop).start(); for (int i = 0; i < 1000; i++) { System.out.println("main" + i); if (i == 900){ testStop.stop(); System.out.println("The thread has stopped"); } } } }
4.4 thread sleep
* sleep(Time) specifies the number of milliseconds the current thread is blocking * sleep There is an exception InterruptedException * sleep When the time is up, the thread enters the ready state * sleep Can simulate network delay, countdown, etc * Every object has a lock, sleep The lock will not be released
4.5 yield
package thread.methods; //Test comity thread public class TestYield { public static void main(String[] args) { //lamda expression Runnable myYield = ()->{ System.out.println(Thread.currentThread().getName() + "Thread starts execution"); Thread.yield(); System.out.println(Thread.currentThread().getName() + "End of thread running"); }; 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(); // System.out.println(Thread.currentThread().getName() + "end of thread running"); // } //}
4.6 merge threads (Join)
* Join Merge threads. After this thread completes execution, execute other threads. Other threads are blocked * Imagine jumping in line
package thread.methods; //Test join method public class TestJoin implements Runnable { @Override public void run() { for (int i = 0; i < 1000; i++) { System.out.println("VIP coming" + i); } } public static void main(String[] args) throws InterruptedException { //Start our thread TestJoin testJoin = new TestJoin(); Thread thread = new Thread(testJoin); thread.start(); //Main thread for (int i = 0; i < 500; i++) { if (i == 100){ thread.join(); } System.out.println("main" + i); } } }
4.7 observing thread status
package thread.state; public class TestState { public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(()->{ for (int i = 0; i < 5; i++) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("/"); }); //Observation status (new) Thread.State state = thread.getState(); System.out.println(state); //run thread.start(); state = thread.getState(); System.out.println(state); //As long as the thread does not terminate, it always outputs the state while (state != Thread.State.TERMINATED){ Thread.sleep(100); state = thread.getState();//Update thread status System.out.println(state); } } }
5. Thread priority
Low priority only means that the probability of obtaining scheduling is low, not that it will not be called if the priority is low, which depends on CPU scheduling
* The priority of a thread is expressed in numbers, ranging from 1~10 * Thread.MIN_PRIORITY = 1 * Thread.MAX_PRIORITY =10 * Thread.NORM_PRIORITY = 5 * Change or get priority in the following ways * getPriority() * setPriority(int xxx)
package thread.state; //Test thread priority public class TestPriority { public static void main(String[] args) { //Main thread priority System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority()); //Create thread MyPriority myPriority = new MyPriority(); Thread t1 = new Thread(myPriority); Thread t2 = new Thread(myPriority); Thread t3 = new Thread(myPriority); Thread t6 = new Thread(myPriority); t1.setPriority(10); t1.start(); t2.start(); t3.setPriority(8); t3.start(); t6.setPriority(1); t6.start(); } } class MyPriority implements Runnable{ @Override public void run() { System.out.println(Thread.currentThread().getName() + "-->" +Thread.currentThread().getPriority()); } }
6. daemon thread
* Threads are divided into user threads and daemon threads * The virtual machine must ensure that the user thread has completed execution( main) * The virtual machine does not have to wait for the daemon thread to complete execution, such as recording operation logs in the background, monitoring memory, garbage collection and so on( gc)
package thread.methods; //Test daemon thread public class TestDaemon { public static void main(String[] args) { Love love = new Love(); You you = new You(); Thread thread = new Thread(love); thread.setDaemon(true);//The default is false, indicating that it is a user thread thread.start();//Daemon thread start new Thread(you).start();//User thread start } } //Daemon thread class Love implements Runnable{ @Override public void run() { while (true){ System.out.println("Love is with you"); } } } //User thread class You implements Runnable{ @Override public void run() { for (int i = 0; i < 36500; i++) { System.out.println("Alone, company"); } System.out.println("-====goodbye!world!====-"); } }
7. Thread synchronization
Concurrency: the same object is operated by multiple threads at the same time, forming conditions: queue and lock (lock mechanism synchronized)
* Tens of thousands of people robbed 100 tickets at the same time * Two banks withdraw money at the same time
7.1 three unsafe cases
package thread.syn; //Unsafe ticket buying //Thread unsafe, negative number public class UnsafeBuyTicket { public static void main(String[] args) { BuyTicket buyTicket = new BuyTicket(); new Thread(buyTicket, "Xiao Ming").start(); new Thread(buyTicket, "Xiao Hong").start(); new Thread(buyTicket, "Xiao Jie").start(); } } class BuyTicket implements Runnable{ private int ticketNums = 10; boolean flag = true; public void run() { while (flag){ if (ticketNums <= 1) flag = false; try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " Get" + ticketNums--); } } }
package thread.syn; //Bank withdrawal public class UnsafeBank { public static void main(String[] args) { Account account = new Account(100000, "Marriage fund"); Drawing you = new Drawing(account, 5000, "yourself"); Drawing yourWife = new Drawing(account, 10000, "yourWife"); you.start(); yourWife.start(); } } class Account{ int money; String name; public Account(int money, String name) { this.money = money; this.name = name; } } class Drawing extends Thread{ Account account; int drawingMoney; int nowMoney; public Drawing(Account account, int drawingMoney, String name){ super(name); this.account = account; this.drawingMoney = drawingMoney; } @Override public void run() { if (account.money - drawingMoney < 0){ System.out.println(this.getName()+ "Sorry, your credit is running low"); return; } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } account.money = account.money - drawingMoney; nowMoney = nowMoney + drawingMoney; System.out.println(account.name + "The balance is" + account.money); //Thread.currentThread().getName() == this.getName(); System.out.println(this.getName() + "The money in hand is" + nowMoney); } }
package thread.syn; //form import java.util.ArrayList; import java.util.List; public class UnsafeList { public static void main(String[] args) { List<String> list = new ArrayList<String>(); for (int i = 0; i < 100000; i++) { new Thread(()->{list.add(Thread.currentThread().getName());}).start(); } try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(list.size()); } }
7.2 synchronization method
The synchronization listener of the public synchronized void method(int args) {} synchronization method is this, that is, the object itself or class
package thread.syn; //Buy a ticket safely public class UnsafeBuyTicket { public static void main(String[] args) { BuyTicket buyTicket = new BuyTicket(); new Thread(buyTicket, "Xiao Ming").start(); new Thread(buyTicket, "Xiao Hong").start(); new Thread(buyTicket, "Xiao Jie").start(); } } class BuyTicket implements Runnable{ private int ticketNums = 10; boolean flag = true; public void run() { while (flag){ buy(); } } //The synchronized synchronization method locks this private synchronized void buy() { if (ticketNums <= 0) {flag = false;return;} try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " Get" + ticketNums--); } }
7.3 synchronization block
synchronized (Obj) {} Obj can be any object, but it is recommended to use shared resources (addition, deletion and modification) as the synchronization monitor
* Synchronization monitor execution * The first thread accesses, locks the synchronization monitor, and executes the code in it. * The second thread accesses and finds that the synchronization monitor is locked and cannot be accessed * After the first thread is accessed, unlock the synchronization monitor * The second thread accesses, finds that the synchronization monitor has no lock, and then locks and accesses
package thread.syn; public class UnsafeBank { public static void main(String[] args) { Account account = new Account(100000, "Marriage fund"); Drawing you = new Drawing(account, 5000, "yourself"); Drawing yourWife = new Drawing(account, 10000, "yourWife"); you.start(); yourWife.start(); } } class Account{ int money; String name; public Account(int money, String name) { this.money = money; this.name = name; } } class Drawing extends Thread{ Account account; int drawingMoney; int nowMoney; public Drawing(Account account, int drawingMoney, String name){ super(name); this.account = account; this.drawingMoney = drawingMoney; } @Override public void run() { synchronized (account){ if (account.money - drawingMoney < 0){ System.out.println(this.getName()+ "Sorry, your credit is running low"); return; } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } account.money = account.money - drawingMoney; nowMoney = nowMoney + drawingMoney; System.out.println(account.name + "The balance is" + account.money); //Thread.currentThread().getName() == this.getName(); System.out.println(this.getName() + "The money in hand is" + nowMoney); } } }
package thread.syn; import java.util.ArrayList; import java.util.List; public class UnsafeList { public static void main(String[] args) { List<String> list = new ArrayList<String>(); for (int i = 0; i < 100000; i++) { new Thread(()->{ synchronized (list){ list.add(Thread.currentThread().getName());} }).start(); } try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(list.size()); } }
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<String>(); List with lock
package thread.syn; import java.util.concurrent.CopyOnWriteArrayList; //Testing a collection of JUC security types public class TestJUC { public static void main(String[] args) { CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<String>(); for (int i = 0; i < 10000; i++) { new Thread(()-> list.add(Thread.currentThread().getName())).start(); } try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(list.size()); } }
7.4 deadlock
Deadlock: a synchronization block has "locks of more than two objects" at the same time
package thread.syn; //Deadlock: multiple threads hold each other's required resources, and then form a deadlock public class DeadLock { public static void main(String[] args) { MakeUp g1 = new MakeUp(0,"Cinderella"); MakeUp g2 = new MakeUp(1,"Snow White"); g1.start(); g2.start(); } } //Lipstick class LipStick{} //mirror class Mirror{} class MakeUp extends Thread { //Only one resource is needed, which is guaranteed by static static LipStick lipStick = new LipStick(); static Mirror mirror = new Mirror(); int choice;//choice String name;//People who use cosmetics MakeUp(int choice, String name) { this.choice = choice; this.name = name; } @Override public void run() { try { makeup(); } catch (InterruptedException e) { e.printStackTrace(); } } //Make up and hold each other's resources private void makeup() throws InterruptedException { if (choice == 0) { synchronized (lipStick) {//Get lipstick lock System.out.println(this.name + "Get lipstick"); Thread.sleep(1000); } synchronized (mirror) {//Get the lock of the mirror System.out.println(this.name + "Get the lock of the mirror"); } } else { synchronized (mirror) {//Get the lock of the mirror System.out.println(this.name + "Get the lock of the mirror"); Thread.sleep(2000); } synchronized (lipStick) {//Get lipstick lock System.out.println(this.name + "Get lipstick lock"); } } } }
7.5 explicit LOCK
package thread.syn; import java.util.concurrent.locks.ReentrantLock; public class TestLock { public static void main(String[] args) { TestLock2 testLock2 = new TestLock2(); new Thread(testLock2, "Xiao Ming").start(); new Thread(testLock2, "Xiao Jie").start(); new Thread(testLock2, "Xiao Wang").start(); } } class TestLock2 implements Runnable{ private int tickNums = 10; boolean flag = true; private final ReentrantLock reentrantLock = new ReentrantLock(); @Override public void run() { try{ reentrantLock.lock(); while (flag){ if (tickNums <= 0 ){ flag = false; return; } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "Got" + tickNums--); } }finally { reentrantLock.unlock(); } } }
8. Thread collaboration
Producer consumer problem: producers and consumers share the same resource, and producers and consumers are interdependent and conditional on each other
effect | Method name |
---|---|
It means that the thread waits until other threads notify it. Unlike sleep, it will release the lock | wait() |
Specifies the number of milliseconds to wait | wait(long timeout) |
Wake up a waiting thread | notify() |
Wake up all threads calling the wait() method on the same object, and the threads with high priority are scheduled first | notifyAll() |
8.1 solution 1
Concurrent collaboration model "producer / consumer model" -- > management method
* Producer: the module responsible for production data (may be method, object, thread, process) * Consumer: module responsible for processing data (may be method, object, thread, process) * Buffer: consumers cannot directly use the producer's data. There is a "buffer" between them
The producer puts the produced data into the buffer, and the consumer takes out the data from the buffer
Video link
package thread.itc; //Test: producer consumer model -- > tube process method public class TestPC { public static void main(String[] args) { SynContainer container = new SynContainer(); new Producer(container).start(); new Consumer(container).start(); } } //producer class Producer extends Thread{ SynContainer container; public Producer(SynContainer container){ this.container = container; } //production @Override public void run() { for (int i = 1; i < 100; i++) { container.push(new Chicken(i)); System.out.println("Produced" + i + "Chicken"); try { Thread.sleep(0); } catch (InterruptedException e) { e.printStackTrace(); } } } } //consumer class Consumer extends Thread{ SynContainer container; public Consumer(SynContainer container){ this.container = container; } //consumption @Override public void run() { for (int i = 1; i < 100; i++) { System.out.println("Consumption-->" + container.pop().id + "Chicken"); try { Thread.sleep(0); } catch (InterruptedException e) { e.printStackTrace(); } } } } //product class Chicken{ int id; public Chicken(int id) { this.id = id; } } //buffer class SynContainer{ //A container size is required Chicken[] chickens = new Chicken[10]; //Container counter int count = 0; //The producer puts in the product public synchronized void push(Chicken chicken){ //If the container is full, it needs to wait for consumers to consume if(count == chickens.length){ //Inform consumers of consumption, production and waiting try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //If not, throw in the product chickens[count] = chicken; count++; //Consumers can be notified to consume products this.notifyAll(); } //Consumer products public synchronized Chicken pop(){ //Judge whether it can be consumed if (count == 0){ //Waiting for producer production try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //If you can consume count--; Chicken chicken = chickens[count]; //When finished, inform the producer to produce this.notifyAll(); return chicken; } }
8.2 solution 2
Concurrent collaboration model "producer / consumer model" -- > semaphore method
package thread.itc; Testing: producer consumer model-->Signal lamp method public class TestPC2 { public static void main(String[] args) { Program program = new Program(); new Player(program).start(); new Audience(program).start(); } } //Producer -- > actor class Player extends Thread{ Program program; public Player(Program program){ this.program = program; } @Override public void run() { for (int i = 1; i < 20; i++) { this.program.show ("Jay's Special session", i); } } } //Consumer -- > audience class Audience extends Thread{ Program program; public Audience(Program program){ this.program = program; } @Override public void run() { for (int i = 1; i < 20; i++) { this.program.clap(); } } } //Products -- > Programs class Program{ //The actors perform and the audience watch T //The audience applauded and the actor saluted F String name;//A performance int order;//Program serial number boolean flag = true;//Signal lamp //perform public synchronized void show (String name, int order){ if(!flag){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("The actors performed" + name + "The first" + order + "Programs"); //The audience applauded and the actors paid tribute this.notifyAll(); this.name = name; this.order = order; this.flag = !this.flag; } //applause public synchronized void clap(){ if (flag){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("The audience finished watching" + name + "The first" + order + "During the first program, warm applause broke out and the actors bowed"); this.notifyAll(); this.flag = !this.flag; } }
9. Thread pool
* Background: resources that are often created and destroyed and used heavily, such as threads in concurrency, have a great impact on performance * Idea: create many threads in advance and put them into the thread pool. When using, they can be obtained directly and put them back into the pool after use. It can avoid complex creation, destruction and reuse. Similar to public transport (bicycle) in life. * Benefits: * Improved response time (reduced time to create new threads) * Reduce resource consumption (reuse threads in the thread pool instead of creating them every time) * Easy thread management
newFixedThreadPool: size of thread pool corePoolSize: size of core pool maximumPoolSize: maximum number of threads keepAliveTime: how long does the thread last when there is no task
API related to thread pool: ExecutorService and Executors void execute(Runnable command): execute tasks / commands without return value. It is generally used to execute runnable < T > Future < T > submit (callable < T > task): execute tasks with return value. It is generally used to execute Callablevoid shutdown(): close connection pool Executors: tool class and factory class of thread pool, Used to create and return different types of thread pools
package thread.syn; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; //Test thread pool public class TestPool { public static void main(String[] args) { //1. Create thread pool ExecutorService service = Executors.newFixedThreadPool(10); service.execute(new MyThread()); service.execute(new MyThread()); service.execute(new MyThread()); service.execute(new MyThread()); //2. Close the connection service.shutdown(); } } class MyThread implements Runnable{ @Override public void run() { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + " " + i); } } }