Multi thread learning
1. Multithreading_ concept
Multithreading, in short, is multitasking.
Inter method call: an ordinary method call is a closed path from where to where.
Multithreading: opens up multiple paths.
2. Multithreading_ Inherit Thread
There are three ways to create threads:
- (1) Inherit Thread
- (2) Implement Runnable interface
- (3) Implement Callable interface (just understand)
Key points: less inheritance and more implementation
Do you know what the three high problem is?
High availability, high performance and high concurrency
Knock the code and you'll know.
public class Test1 extends Thread { //Create access port @Override public void run() { for(int i=0;i<20;i++) { System.out.println("Knock code"); } } public static void main(String[] args) { /* * Thread creation mode 1: * Inherit Thread + override run */ //Create subclass objects Test1 st=new Test1(); //start-up st.start(); //Immediate operation is not guaranteed, cpu calls // st.run(); // Method call for(int i=0;i<20;i++) { System.out.println("I am learning"); } } }
3. Multithreading_ Picture download
Know that using multithreading to download online pictures is also a necessary skill!
/* * Download pictures */ public class Test2 { public void download(String url,String name) { try { FileUtils.copyURLToFile(new URL(url),new File(name)); } catch (MalformedURLException e) { e.printStackTrace(); System.out.println("illegal url!"); } catch (IOException e) { e.printStackTrace(); System.out.println("Download failed!"); } } } public class TDownloader extends Thread { private String url; //Remote path private String name; //Storage path public TDownloader(String url, String name) { this.url = url; this.name = name; } @Override public void run() { Test2 wd=new Test2(); wd.download(url,name); System.out.println(name); } public static void main(String[] args) { TDownloader td1=new TDownloader("Picture URL","p1.jpg"); TDownloader td2=new TDownloader("Picture URL","p2.jpg"); TDownloader td3=new TDownloader("Picture URL","p3.jpg"); //Start three threads td1.start(); td2.start(); td3.start(); } }
Try it after you learn
4. Multithreading_ Implement Runnable
What should you think of when you see the realization?
Yes, it's the interface!
/* * Implement Runnable */ public class Test3 implements Runnable { /* * Thread access point */ @Override public void run() { for(int i=0;i<20;i++) { System.out.println("Knock code"); } } public static void main(String[] args) { new Thread(new Test3()).start(); for(int i=0;i<20;i++) { System.out.println("Listening to music"); } } }
5. Multithreading_ Ticket grabbing_ Tortoise and rabbit race
It's no use learning multithreading without showing its role. This time, we'll implement it with the most familiar turtle and rabbit race and ticket grabbing problem.
1) Simulated ticket purchase
public class Test4 implements Runnable{ //Number of votes private int tickets=99; @Override public void run() { while(true) { if(tickets<0) { break; } System.out.println(Thread.currentThread().getName()+"-->"+tickets--); } } public static void main(String[] args) { //A resource Test4 web1=new Test4(); //Multiple agents new Thread(web1,"programmer").start(); new Thread(web1,"Code farmer").start(); new Thread(web1,"Development Engineer").start(); } }
2) Simulated tortoise rabbit race
/* * Simulated tortoise rabbit race */ public class Test5 implements Runnable{ private static String winner; //winner @Override public void run() { for(int steps=1;steps<=100;steps++) { //Simulated rest if(Thread.currentThread().getName().equals("rabbbit")&&steps%100==0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName()+"-->"+steps); //Is the game over boolean flag=gameOver(steps); if(flag) { break; } } } private boolean gameOver(int steps) { if(winner!=null) { //There is a winner return true; }else { if(steps==100) { winner=Thread.currentThread().getName(); System.out.println("winner ==>"+winner); return true; } } return false; } public static void main(String[] args) { Test5 racer=new Test5(); new Thread(racer,"tortoise").start(); new Thread(racer,"rabbit").start(); } }
6. Multithreading_ Learn about Callable
Steps to implement Callable:
- 1. Create target object: CDownloader cd=new CDownloader("picture address", "baidu.png") / / CDownloader class name
- 2. Create execution service: executorservice ser = executors newFixedThreadPool(1);
- 3. Submit execution: future res = Ser submit(cd1);
- 4. Get result: boolean r1=res.get();
- 5. Shut down the service: Ser shutdownNow();
7. Multithreading_ Static agent design pattern
/* * Static proxy: * Interface: * 1,Real role * 2,delegable role */ public class Test6 { public static void main(String[] args) { new WeddingCompany(new You()).happy(); //New thread (thread object). start() } } interface Marry{ void happy(); } class You implements Marry{ @Override public void happy() { System.out.println("You and "); } } //delegable role class WeddingCompany implements Marry{ //Real role private Marry target; public WeddingCompany(Marry target) { this.target=target; } @Override public void happy() { ready(); this.target.happy(); after(); } private void ready() { System.out.println("arrangement"); } private void after() { System.out.println("start"); } }
8. Multithreading_ Lambada_ Simplify threads
public class TestLambda { //Static inner class static class Test implements Runnable{ public void run() { for(int i=0;i<20;i++) { System.out.println("Knock code"); } } } public static void main(String[] args) { //Static inner class // new Thread(new Test()).start(); //Local inner class class Test2 implements Runnable{ public void run() { for(int i=0;i<20;i++) { System.out.println("Knock code"); } } } //Local inner class // new Thread(new Test2()).start(); //Anonymous Inner Class new Thread(new Runnable() { public void run() { for(int i=0;i<20;i++) { System.out.println("Knock code"); } } }).start(); //jdk8 simplified lambda is used to simplify simple threads. Only one method can be deduced new Thread(()->{ for(int i=0;i<20;i++) { System.out.println("Knock code"); } }).start(); } }
Warm tip: lambda: you can take parameters, omit curly braces for one sentence, and omit type names (multiple parameters are OK)
9. Multithreading_ termination
public class Test7 implements Runnable{ //Add a sign to mark whether the layer body can run private boolean flag=true; private String name; public Test7(String name) { this.name=name; } @Override public void run() { int i=0; //Association flag true -- > Run false -- > stop while(flag) { System.out.println(name+"-->"+i++); } } //3. External provision method change sign public void Test7() { this.flag=false; } public static void main(String[] args) { Test7 tt=new Test7("xiaoha"); new Thread(tt).start(); for(int i=0;i<99;i++) { if(i==88) { tt.Test7(); System.out.println("game Over"); } System.out.println("main-->"+i); } } }
10. Multithreading_ Pause sleep
Case: 12306 ticket purchase, tortoise and rabbit race
Do it yourself
11. Multithreading_ yield
Knowledge point: yield the thread to pause. The thread directly enters the ready state, not the blocking state
public class TestYield { public static void main(String[] args) { MyYield my=new MyYield(); new Thread(my,"a").start(); new Thread(my,"b").start(); } } class MyYield implements Runnable{ @Override public void run() { System.out.println(Thread.currentThread().getName()+"-->start");; Thread.yield(); System.out.println(Thread.currentThread().getName()+"-->end");; } }
12. Multithreading_ Jump the queue join
Knowledge point: join: merge thread queue thread
public class TestJoin { public static void main(String[] args) { System.out.println("The story of father and son buying cigarettes"); new Thread(new Father()).start(); } } class Father extends Thread{ public void run() { System.out.println("I wanted to smoke, but I didn't find it"); System.out.println("Let my son buy cigarettes"); Thread t=new Thread(new Son()); t.start(); try { t.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Dad took the cigarette and gave him the change"); } } class Son extends Thread{ public void run() { System.out.println("Take dad's money.."); System.out.println("There was a game console on the side of the road. I played it for a while"); for(int i=0;i<10;i++) { System.out.println(i+"Seconds have passed"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("Hurry to buy cigarettes.."); System.out.println("He went home with a pack of cigarettes in his hand.."); } }
13. Multithreading_ Deep observation state
Knowledge points: blocking status: sleep, join, wait, read, write
public class AllState { public static void main(String[] args) { Thread tt=new Thread(()->{ for(int i=0;i<5;i++) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("....."); }); //Observation state State state=tt.getState(); System.out.println(state); //NEW tt.start(); state=tt.getState(); //RUNNING while(state!=Thread.State.TERMINATED) { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } state=tt.getState(); System.out.println(state); //TIMED_WAITING } } }
14. Multithreading_ priority
- 1,NORM_PRIORITY
- 2,MIN_PRIORITY
- 3,MAX_PRIORITY
- Probability does not represent absolute order
public class TestPriority { public static void main(String[] args) { System.out.println(Thread.currentThread().getPriority()); MyPriority mp=new MyPriority(); Thread t1=new Thread(mp,"Double happiness"); Thread t2=new Thread(mp,"Warrior "); Thread t3=new Thread(mp,"NIKE"); Thread t4=new Thread(mp,"Li Ning"); t1.setPriority(Thread.NORM_PRIORITY); t2.setPriority(Thread.MIN_PRIORITY); t3.setPriority(Thread.MAX_PRIORITY); t4.setPriority(Thread.MIN_PRIORITY); t1.start(); t2.start(); t3.start(); t4.start(); } } class MyPriority implements Runnable { @Override public void run() { System.out.println(Thread.currentThread().getName()+"--->"+Thread.currentThread().getPriority()); } }
15. Multithreading_ Daemon thread
Knowledge point: guard thread: it serves user threads; The jvm stops without waiting for the daemon thread to finish executing
public class Test8 { public static void main(String[] args) { God god=new God(); Ni you=new Ni(); // new Thread(god).start(); Thread t=new Thread(god); t.setDaemon(true); //Adjust user thread to daemon t.start(); new Thread(you).start(); } } class Ni implements Runnable{ @Override public void run() { for(int i=0;i<=365*100;i++) { System.out.println("happy life"); } System.out.println("hahaah"); } } class God implements Runnable{ @Override public void run() { for(;true;) { System.out.println("belss you"); } } }
16. Multithreading_ Basic information_ Net red thinking
- isAlive: is the thread still alive
- Thread.currentThread(): current thread
- setName, getName: Agent Name
public class Test9 { public static void main(String[] args) { System.out.println(Thread.currentThread().isAlive()); //-->true //Setting Name: real role + proxy role MyInfo info=new MyInfo("audi"); Thread t=new Thread(info); t.setName("Benz"); t.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(t.isAlive()); //-->false } } class MyInfo implements Runnable{ private String name; public MyInfo(String name) { this.name=name; } @Override public void run() { System.out.println(Thread.currentThread().getName()+name); } }
17. Multithreading_ Concurrent_ Asynchronous_ Three classic cases
- Thread unsafe: data is negative and the same
- Thread unsafe: withdraw money
public class UnsafeTest1 { public static void main(String[] args) { //account Account account=new Account(100,"Wedding gift");; Drawing you=new Drawing(account,80,"Lovely you"); Drawing wife=new Drawing(account,90,"happy"); you.start(); wife.start(); } } //account class Account{ int money; //amount of money String name; //name public Account(int money,String name) { this.money=money; this.name=name; } } //Simulated withdrawal class Drawing extends Thread{ Account account; //Withdrawal account int drawingMoney; //Amount of money obtained int drawingTotal; //Get total int packetTotal; //Total number of pockets 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){ return ; } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } account.money-=drawingMoney; packetTotal+=drawingMoney; System.out.println(this.getName()+"-->"+"The balance of the account is:"+account.money); System.out.println(this.getName()+"-->"+"The money in the pocket is:"+packetTotal); } }
18. Multithreading_ Concurrent_ Synchronization_ Queues and locks
- Thread safety: ensure the correctness and efficiency of data during concurrency
- synchronize
19. Multithreading_ Concurrent_ Synchronization_ synchronized synchronization block
- synchronized(): lock the correct object
- When manipulating containers and objects
20. Multithreading_ Concurrent_ Synchronization_ performance analysis
- Thread is unsafe. The range is too small to lock
- Lock in a reasonable range as much as possible
21. Multithreading_ Concurrent_ Synchronization_ Happy cinema
public class TestSyn { public static void main(String[] args) { Cinema c=new Cinema(20,"Specific height"); new Thread(new Customer(c,3),"xiaoda").start(); new Thread(new Customer(c,2),"xiaoha").start(); } } //customer class Customer implements Runnable{ Cinema cinema; int seat; public Customer(Cinema cinema, int seat) { super(); this.cinema = cinema; this.seat = seat; } @Override public void run() { synchronized (cinema) { boolean flag=cinema.bookTickets(seat); if(flag) { System.out.println("Ticket issued successfully"+Thread.currentThread().getName()+"--->Location is"+seat); }else { System.out.println("Ticket issuing failed"+Thread.currentThread().getName()+"--->Insufficient position"); } } } } //cinema class Cinema{ int available; //Available locations String name; //name public Cinema(int available, String name) { super(); this.available = available; this.name = name; } //Ticket purchase public boolean bookTickets(int seat) { System.out.println("Available locations:"+available); if(seat>available) { return false; }; available-=seat; return true; } }
22. Multithreading_ Concurrent_ Deadlock_ Generation and solution
- Deadlock: too many synchronizations may cause mutual non release of resources
- Thus, they wait for each other, which usually occurs when they hold locks of multiple objects in synchronization
- Avoid: do not hold multiple object locks in the same code block at the same time
public class TestSyn{ public static void main(String[] args) { MakeUp g1=new MakeUp(1,"qiqi"); MakeUp g2=new MakeUp(2,"gaga"); g1.start(); g2.start(); } } //Lipstick class LipStick{ } //mirror class Mirror{ } //Make up class MakeUp extends Thread{ static LipStick lipstick=new LipStick(); static Mirror mirror=new Mirror(); //choice int choice; //name String name; public MakeUp(int choice, String name) { super(); this.choice = choice; this.name = name; } @Override public void run() { //Make up makeup(); } //Holding each other's object lock -- > may cause deadlock private void makeup() { if(choice==0) { synchronized (lipstick) { //Get lipstick lock System.out.println(this.name+"Get lipstick"); //I want to have a mirror in 1 second try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } // synchronized (mirror) { // System.out.println(this.name + "get a mirror"); // } } synchronized (mirror) { System.out.println(this.name+"Get mirror"); } }else { synchronized (mirror) { System.out.println(this.name+"Get mirror"); //Want to have lipstick in 2 seconds try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } // synchronized (lipstick) {/ / get the lock of lipstick // System.out.println(this.name + "get lipstick"); // } } synchronized (lipstick) { //Get lipstick lock System.out.println(this.name+"Get lipstick"); } } } }
23. Multithreading_ Concurrent collaboration_ Producer consumer model
Solution 1: concurrent collaboration model > management method
Producer: the module responsible for production data. (the modules here may be: methods, objects, threads and processes)
Consumer: the module responsible for processing data. (the modules here may be: methods, objects, threads and processes)
Buffer: consumers cannot directly use the producer's data. There is a buffer between them
Solution 2: concurrent collaboration model - > semaphore method
24. Multithreading_ Concurrent collaboration_ Pipe program method
- Collaboration model: producer consumer - > pipe process method
- Create a buffer
public class TestCusPro { public static void main(String[] args) { SynContainer container=new SynContainer(); new Producer(container).start(); new Customer(container).start(); } } //producer class Producer extends Thread{ SynContainer container; public Producer(SynContainer container) { this.container=container; } public void run() { //production for(int i=0;i<100;i++){ System.out.println("production"+i+"Items"); container.push(new Goods(i)); } } } //consumer class Customer extends Thread{ SynContainer container; public Customer(SynContainer container) { this.container=container; } public void run() { //consumption for(int i=0;i<100;i++) { //Change 1000 to 100, or you'll be waiting System.out.println("consumption"+container.pop().id+"Items"); } } } //buffer class SynContainer{ Goods[] goods=new Goods[10]; //Storage container int count=0; //Counter //Storage production public synchronized void push(Goods good) { //When can production containers exist //No production, only waiting if(count==goods.length) { try { this.wait(); //Thread blocking consumer notifies production release } catch (InterruptedException e) { e.printStackTrace(); } } //There is room for production goods[count]=good; count++; //There is data to inform consumption this.notifyAll(); } //Obtain consumption public synchronized Goods pop() { //When is there data in the consumer container //No data can only wait if(count==0) { try { this.wait(); //Thread blocking producer notifies consumer to release } catch (InterruptedException e) { e.printStackTrace(); } } //Existing data can be consumed count--; Goods good=goods[count]; this.notifyAll(); //There is room to awaken each other's production return good; } } //commodity class Goods{ int id; public Goods(int id) { super(); this.id = id; } }
25. Multithreading_ Concurrent collaboration_ Signal lamp
- Collaboration model: producer consumer implementation mode 2: signal lamp
- With the help of flag bit
public class TestXinhaoDe { public static void main(String[] args) { TV tv=new TV(); new Player(tv).start(); new Listener(tv).start(); } } //Producer actor class Player extends Thread{ TV tv; public Player(TV tv) { super(); this.tv = tv; } public void run() { for(int i=0;i<20;i++) { if(i%2==0) { this.tv.play("music"); }else { this.tv.play("movie"); } } } } //Consumer audience class Listener extends Thread{ TV tv; public Listener(TV tv) { super(); this.tv = tv; } public void run() { for(int i=0;i<20;i++) { tv.Watch(); } } } //Same resource TV class TV{ String voice; //Signal lamp //T means the actor performs and the audience waits //F means the audience watches the actors wait boolean flag=true; //perform public synchronized void play(String voice) { //Actor waiting if(!flag) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //perform System.out.println("Performed"+voice); this.voice=voice; //awaken this.notifyAll(); //Switch flag this.flag=!this.flag; } //watch public synchronized void Watch() { //Audience waiting if(flag) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //watch System.out.println("Yes"+voice); //awaken this.notifyAll(); //Switch flag this.flag=!this.flag; } }
26. Multithreading_ Advanced topics_ Timing scheduling
Task scheduling: with the help of Timer and TimerTask classes
public class TestTiime { public static void main(String[] args) { Timer time=new Timer(); //Implementation arrangements // time.schedule(new MyTask(),1000); // Perform the task once // time.schedule(new MyTask(),1000,200); // Execute multiple times Calendar cal=new GregorianCalendar(2021,12,30,12,30,20); // time. schedule(new MyTask(),new Date(5000L),200); // Start in 5 seconds time.schedule(new MyTask(),cal.getTime(),200); } } //Task class class MyTask extends TimerTask{ @Override public void run() { for(int i=0;i<10;i++) { System.out.println("Take a break"); } System.out.println("-----end------"); } }
27. Multithreading_ Advanced topics_ QUARTZ
Official website: quartz
28. Multithreading_ Advanced topics_ happenbefore
HappenBefore: the order of executing code may be inconsistent with that of the written code, that is, if the virtual machine optimizes the code order, it is instruction rearrangement.
Data dependency:
- (1) Read after writing a=1;b=a;
- (2) Write after write: a=1;a=2;
- (3) Write after reading: a=b;b=1;
In the above three cases, as long as the execution order of the two operations is reordered, the execution result of the program will be changed. Therefore, compiler and processor will abide by data dependency when reordering. The compiler and processor do not change the execution order of the two operations of the data dependency.
/* * Instruction rearrangement: the execution order of the code is inconsistent with that expected * Objective: to improve performance */ public class Test { //Variable 1 private static int a=0; //Variable 2 private static boolean flag=false; public static void main(String[] args) throws InterruptedException { //Thread 1 changes data Thread t1=new Thread(()->{ a=1; flag=true; }); //Thread 2 reads data Thread t2=new Thread(()-> { if(flag) { a*=1; } //Instruction rearrangement if(a==0) { System.out.println("happen before a"+a); } }); t1.start(); t2.start(); t1.join(); t2.join(); } }
The code has some problems and does not get the correct output. If anyone knows what's wrong, please leave a comment!
29. Multithreading_ Advanced topics_ volatile
volatile ensures the visibility of variables between threads.
Objective: to improve efficiency
Volatile is a good mechanism, but volatile cannot guarantee atomicity.
/* * volatile: It is used to ensure data synchronization, that is, visibility */ public class Testvolatile { // private static int num=0; private volatile static int num=0; public static void main(String[] args) throws InterruptedException { new Thread(()->{ while(num==0) { //Don't write code here } }).start(); Thread.sleep(1000); num=1; } }
30. Multithreading_ Advanced topics_ dcl singleton mode
dcl singleton mode: Based on the lazy routine, it ensures that there is an external object in the multithreaded environment
- 1. Constructor privatization – > avoid external new constructors
- 2. Provide private static properties – > store the address of the object
- 3. Provide public static methods – > get properties
public class Test1 { //2. Provide private static properties private volatile static Test1 instance; //Avoid instruction rearrangement //Without volatile, other threads may access an object that is not initialized //1. Constructor privatization private Test1() { } //3. Provide public static methods public static Test1 getInstance() { //Retest if(null!=instance) { //Avoid unnecessary synchronization. Objects already exist return instance; } synchronized (Test1.class) { if(null==instance) { instance=new Test1(); //(three things new does): 1. Open up space 2. Initialize object information 3. Return the address of the object to the reference } } return instance; } public static void main(String[] args) { Thread t=new Thread(()->{ System.out.println(Test1.getInstance()); }); t.start(); System.out.println(Test1.getInstance()); } }
31. Multithreading_ Advanced topics_ ThreadLocal
ThreadLocal is most commonly used to bind a database link, HTTP request, user identity information, etc. for each thread. All the methods called by such a thread can easily access these resources.
- (1) HIbernate Session tool class HIbernateUtil
- (2) Set Bean properties through different thread objects to ensure the independence of each thread Bean object.
/* * ThreadLoacal:Each thread's own local storage. Local area * get/set/initialValue */ public class Test3 { // private static ThreadLocal<Integer> threadLocal=new ThreadLocal<>(); //Change initial value // private static ThreadLocal<Integer> threadLocal=new ThreadLocal<>() { // protected Integer initialValue() { // return 200; // }; // }; /* * Mode 2: lambda */ private static ThreadLocal<Integer> threadLocal=ThreadLocal.withInitial(()->200); public static void main(String[] args) { //Get value // System.out.println(Thread.currentThread().getName()+"-->"+threadLocal.get()); //-->main-->null System.out.println(Thread.currentThread().getName()+"-->"+threadLocal.get()); //-->main-->200 //Set value threadLocal.set(99); System.out.println(Thread.currentThread().getName()+"-->"+threadLocal.get()); //-->main-->99 } }
ThreadLocal: starting point of analysis context
1. Constructor: it belongs to wherever it is called
2. run method: the method of the thread itself
InheritableThreadLocal: copy the data starting point of the inherited context environment to the child thread
32. Multithreading_ Advanced topics_ Reentrant lock_ Principle realization
1) Reentrant lock: the lock can be used continuously
public class Test4 { public void test() { //Get lock for the first time synchronized (this) { while(true) { //Get the same lock a second time synchronized (this) { System.out.println("ReentrantLock"); } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } public static void main(String[] args) { new Test4().test(); } }
2) Non reentrant lock
public class Test4{ Lock lock=new Lock(); public void a() throws InterruptedException { lock.lock(); doSomething(); lock.unlock(); } //Non reentrant public void doSomething() { try { lock.lock(); } catch (InterruptedException e) { e.printStackTrace(); } lock.unlock(); } public static void main(String[] args) throws InterruptedException { Test4 test=new Test4(); test.a(); test.doSomething(); } }
//Non reentrant lock class Lock{ //Occupied private boolean isLocked=false; //Use lock public synchronized void lock() throws InterruptedException { while(isLocked) { wait(); } isLocked=true; } //Release lock public synchronized void unlock() { } }
33. Multithreading_ Advanced topics_ CAS_ Atomic operation
Locks fall into two categories:
(1) Pessimistic lock: synchronized is an exclusive lock, that is, a pessimistic lock. It will cause all other threads that need a lock to hang and wait for the thread holding the lock to release the lock.
(2) Optimistic lock: complete an operation without locking each time, assuming that there is no conflict. If it fails due to the conflict, try again until it succeeds.
/* * CAS: Compare and exchange */ public class CAS { //stock private static AtomicInteger stock=new AtomicInteger(5); public static void main(String[] args) { for(int i=0;i<5;i++) { new Thread(()->{ //Analog network delay try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } Integer left=stock.decrementAndGet(); if(left<1) { System.out.println("It's over...."); return ; } System.out.println(Thread.currentThread().getName()+"Robbed a commodity"); System.out.println("-->Remaining"+left); }).start(); } } }
Previous blog post: Learning java_ IO_ This is enough