meaning
When dealing with multithreading, multiple threads access the same object, and some threads also want to modify the object. After that, we need thread synchronization. Thread synchronization is actually a waiting mechanism. Multiple threads that need to access the object at the same time enter the waiting pool of the object to form a queue, wait for the previous thread to use it, and then use it again for the next thread.
Forming condition: queue + lock
Lock (synchronized implicit lock)
Because multiple threads of the same process share the same storage space, it brings convenience and access conflict. In order to ensure the correctness of data access in the method, the lock mechanism synchronized is added during access. At present, one thread obtains the exclusive lock of the object and monopolizes resources. Other threads must wait and release the lock after use.
Problems:
1. A thread holding a lock will cause other threads that need the lock to hang;
2. In multi-threaded competition, locking and releasing locks will lead to more context switching and scheduling delays, resulting in performance problems.
3. If a thread with high priority waits for a thread with low priority to release the lock, it will cause priority inversion and performance problems
Unsafe thread test
package com.Thread; //Unsafe thread test public class UnSafeTest { public static void main(String[] args) { //account Account account=new Account(100,"Marriage fund"); Drawing you =new Drawing(account,50,"you"); Drawing me =new Drawing(account,100,"I"); you.start(); me.start(); } } //account class Account{ int money; String name; public Account(int money, String name) { this.money = money; this.name = name; } } //Bank: simulated withdrawal class Drawing extends Thread{ Account account;//account //How much did you withdraw int drawingMoney; //How much money do you have now 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(Thread.currentThread().getName()+"There's not enough money to withdraw"); return; } //sleep can amplify the occurrence of problems try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } //Card balance account.money=account.money-drawingMoney; //The money in your hand nowMoney=nowMoney+drawingMoney; System.out.println(account.name+"The balance is"+account.money); System.out.println(this.getName()+"Money in hand"+nowMoney); } }
Synchronization method
Because we can use the private keyword to ensure that data objects can only be accessed by methods, we only need to propose a mechanism for methods. This mechanism is the synchronized keyword, which includes two uses: the synchronized method and the synchronized block
Synchronized methods control access to "objects". Each object has a lock. Each synchronized method must obtain the lock of the object calling the method before it can be executed. Otherwise, the thread will block. Once the method is executed, it will monopolize the lock until the method returns. The blocked thread can obtain the lock and continue to execute
**Defect: * * declaring a large method synchronized will affect efficiency
Synchronization block
Synchronous thread test:
Lock the object of the class whose properties will changepackage com.Thread; //Unsafe thread test public class UnSafeTest { public static void main(String[] args) { //account Account account=new Account(100,"Marriage fund"); Drawing you =new Drawing(account,50,"you"); Drawing me =new Drawing(account,100,"I"); you.start(); me.start(); } } //account class Account{ int money; String name; public Account(int money, String name) { this.money = money; this.name = name; } } //Bank: simulated withdrawal class Drawing extends Thread{ Account account;//account //How much did you withdraw int drawingMoney; //How much money do you have now int nowMoney; public Drawing(Account account, int drawingMoney, String name) { super(name); this.account = account; this.drawingMoney = drawingMoney; } @Override public void run() { //The object of the lock is the amount of change, which needs to be added, deleted and modified synchronized (account){ if(account.money-drawingMoney<0){ System.out.println(Thread.currentThread().getName()+"There's not enough money to withdraw"); return; } //sleep can amplify the occurrence of problems try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } //Card balance account.money=account.money-drawingMoney; //The money in your hand nowMoney=nowMoney+drawingMoney; System.out.println(account.name+"The balance is"+account.money); System.out.println(this.getName()+"Money in hand"+nowMoney); } } }
JUC security type test (java.util.concurrent)
Lock (lock display lock)
ReentrantLock (reentrant Lock) class implements Lock. It has the same concurrency and memory semantics as synchronized. ReentrantLock is commonly used in thread safety control, which can display locking and releasing locks
package com.Thread2; import java.util.concurrent.locks.ReentrantLock; public class JUCLock { public static void main(String[] args) { Lock lock =new Lock(); new Thread(lock).start(); new Thread(lock).start(); new Thread(lock).start(); } static class Lock implements Runnable{ private final ReentrantLock lock=new ReentrantLock(); int ticketName=10; @Override public void run() { lock.lock(); try { while (true){ if (ticketName>0){ System.out.println(ticketName--); } else { break; } } }finally { lock.unlock(); } } } }
Note: Unlock and close the lock in try finally.
aggregate
package com.Thread2; import java.util.concurrent.CopyOnWriteArrayList; //A collection of test juc security types public class TestJUC { public static void main(String[] args) throws InterruptedException { CopyOnWriteArrayList<String> list =new CopyOnWriteArrayList(); for (int i = 0; i < 1000; i++) { new Thread(()->{ list.add(Thread.currentThread().getName()); }).start(); } Thread.sleep(1000); System.out.println(list.size()); } }
synchronized vs Lock
1.Lock is a display lock (manually open and close the lock, don't forget to close the lock). synchronized is an implicit lock, which is automatically released out of the scope
2.Lock only has code block lock, and synchronized has code block lock and method lock
3. Using Lock lock, the JVM will spend less time to schedule threads and have better performance. And it has better extensibility (providing more subclasses)
4. Priority:
lock > synchronization code block (has entered the method body and allocated corresponding resources) > synchronization method (outside the method body)
deadlock
meaning
Multiple threads 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. When a synchronization block has locks on more than two objects at the same time, deadlock may occur.
Avoidance method
Four necessary conditions for deadlock generation:
1. Mutually exclusive condition: a resource can only be used by one process at a time.
2. Request and hold condition: when a process is blocked by requesting resources, it will hold on to the resources obtained.
3. Conditions of non deprivation: the resources obtained by the process cannot be forcibly deprived until they are used up.
4. Circular waiting condition: a circular waiting resource relationship is formed between several processes.
Deadlock Demo:
Reason: use one resource at the same time
package com.Thread2; public class DeadLock { public static void main(String[] args) { MakeUp makeUp=new MakeUp(0,"Sad little girl"); MakeUp makeUp1=new MakeUp(1,"Vicious old woman"); makeUp.start(); makeUp1.start(); } static class LipsSick{ } static class Mirror{ } static class MakeUp extends Thread{ //Only one resource is needed, and only one is guaranteed by static static LipsSick lipsSick=new LipsSick(); static Mirror Mirror=new Mirror(); int choice; String girlName; public MakeUp(int choice,String girlName){ this.choice=choice; this.girlName=girlName; } @Override public void run() { makeup(); } //Hold each other's locks, compete for the same resource, and form a deadlock private void makeup(){ if (choice==0){ synchronized (lipsSick){ System.out.println(this.girlName+"Got the lipstick"); Thread.sleep(1000); synchronized (Mirror){ System.out.println(this.girlName+"I got the mirror"); } } } else { synchronized (Mirror){ System.out.println(this.girlName+"Got the lipstick"); Thread.sleep(2000); synchronized (lipsSick){ System.out.println(this.girlName+"I got the mirror"); } } } } } }
Unlock:
package com.Thread2; public class DeadLock { public static void main(String[] args) { MakeUp makeUp=new MakeUp(0,"Sad little girl"); MakeUp makeUp1=new MakeUp(1,"Vicious old woman"); makeUp.start(); makeUp1.start(); } static class LipsSick{ } static class Mirror{ } static class MakeUp extends Thread{ //Only one resource is needed, and only one is guaranteed by static static LipsSick lipsSick=new LipsSick(); static Mirror Mirror=new Mirror(); int choice; String girlName; public MakeUp(int choice,String girlName){ this.choice=choice; this.girlName=girlName; } @Override public void run() { makeup(); } private void makeup(){ if (choice==0){ synchronized (lipsSick){ System.out.println(this.girlName+"Got the lipstick"); Thread.sleep(1000); } synchronized (Mirror){ System.out.println(this.girlName+"I got the mirror"); } } else { synchronized (Mirror){ System.out.println(this.girlName+"Got the lipstick"); Thread.sleep(2000); } synchronized (lipsSick){ System.out.println(this.girlName+"I got the mirror"); } } } } }
ps:b station crazy God notes