


Java introduces eight locks to help you thoroughly understand object locks and class locks
Feb 09, 2021 pm 06:06 PMRelated free learning recommendations: java basic tutorial
8 Lock problem demonstration
1. Standard access
/*手機類可以發(fā)郵件和發(fā)短信*/class?Phone{ public?synchronized?void?sendEmail()?throws?Exception{ System.out.println("***sendEmail"); } public?synchronized?void?sendSMS()?throws?Exception{ System.out.println("***sendSMS"); }}public?class?Lock8Demo?{ public?static?void?main(String[]?args)?throws?InterruptedException?{ //創(chuàng)建一個資源類 Phone?phone=new?Phone(); new?Thread(()->{ try?{ phone.sendEmail(); }?catch?(Exception?e)?{ //?TODO?Auto-generated?catch?block e.printStackTrace(); } },"A").start(); Thread.sleep(100); new?Thread(()->{ try?{ phone.sendSMS(); }?catch?(Exception?e)?{ //?TODO?Auto-generated?catch?block e.printStackTrace(); } },"B").start(); }}
Standard access, print email or text message first.
It doesn’t matter who is printed first. It depends on the execution of the CPU. It is the main thread that activates them. I don't know who will be scheduled first later.
In order to ensure the effect, we add thread.sleep(100) between the codes of A and B. At this time, we can ensure that A is printed first.
Explanation:
As long as there is a resource class, no matter how many synchronization methods it has, as long as a thread first accesses any synchronization method in the resource class, then it will not lock this method. is the entire resource class where the method is located. In other words, what is locked is the object. What it locks is not the current method.
In other words, these synchoronized methods all belong to the same resource class, and the entire resource class is locked.
2. Pause for 4 seconds in the email method. Please print the email or text message first.
/*手機類可以發(fā)郵件和發(fā)短信*/class?Phone{ public?synchronized?void?sendEmail()?throws?Exception{ TimeUnit.SECONDS.sleep(4); //表示暫停4秒,它是一個枚舉類型 System.out.println("***sendEmail"); } public?synchronized?void?sendSMS()?throws?Exception{ System.out.println("***sendSMS"); }}public?class?Lock8Demo?{ public?static?void?main(String[]?args)?throws?InterruptedException?{ //創(chuàng)建一個資源類 Phone?phone=new?Phone(); new?Thread(()->{ try?{ phone.sendEmail(); }?catch?(Exception?e)?{ //?TODO?Auto-generated?catch?block e.printStackTrace(); } },"A").start(); Thread.sleep(100); new?Thread(()->{ try?{ phone.sendSMS(); }?catch?(Exception?e)?{ //?TODO?Auto-generated?catch?block e.printStackTrace(); } },"B").start(); }}
Print the email first. The phone object lock obtained by the synchronization method will not be released by sleep. It will be executed immediately when the time comes. So print the email method first
Explanation:
It is similar to question 1.
As long as there is a resource class, no matter how many synchronization methods it has, as long as a thread first accesses any synchronization method in the resource class, it will not lock this method, but the method. The entire resource class. In other words, what is locked is the object. What it locks is not the current method.
For example: The monitor and I need to use the same mobile phone to make a call. I must wait for the monitor to finish the call before I can continue the call. The monitor was disconnected for a while while he was using it, so I could only wait for the monitor to finish.
3. Add the ordinary sayHello method. Please print the email first or hello
Print hello first
/*手機類可以發(fā)郵件和發(fā)短信*/class?Phone{ public?synchronized?void?sendEmail()?throws?Exception{ TimeUnit.SECONDS.sleep(4); //表示暫停4秒,它是一個枚舉類型 System.out.println("***sendEmail"); } public?synchronized?void?sendSMS()?throws?Exception{ System.out.println("***sendSMS"); } public?void?sayHello(){ System.out.println("***sayHello"); }}public?class?Lock8Demo?{ public?static?void?main(String[]?args)?throws?InterruptedException?{ //創(chuàng)建一個資源類 Phone?phone=new?Phone(); new?Thread(()->{ try?{ phone.sendEmail(); }?catch?(Exception?e)?{ //?TODO?Auto-generated?catch?block e.printStackTrace(); } },"A").start(); Thread.sleep(100); new?Thread(()->{ try?{ //phone.sendSMS(); phone.sayHello(); }?catch?(Exception?e)?{ //?TODO?Auto-generated?catch?block e.printStackTrace(); } },"B").start(); }}
Explanation: After adding a common method, it was found that it has nothing to do with synchronization lock. Therefore it does not need to wait for the synchronization lock to be released.
Here is an example. The monitor used his cell phone to make a call. And I want to borrow a mobile phone charging cable from the squad leader. The two are not mutually exclusive, so I can borrow the charging cable before the squad leader finishes calling.
4. Two mobile phones, please print the email or text message first
/*手機類可以發(fā)郵件和發(fā)短信*/class?Phone{ public?synchronized?void?sendEmail()?throws?Exception{ TimeUnit.SECONDS.sleep(4); //表示暫停4秒,它是一個枚舉類型 System.out.println("***sendEmail"); } public?synchronized?void?sendSMS()?throws?Exception{ System.out.println("***sendSMS"); } public?void?sayHello(){ System.out.println("***sayHello"); }}public?class?Lock8Demo?{ public?static?void?main(String[]?args)?throws?InterruptedException?{ //創(chuàng)建一個資源類 Phone?phone=new?Phone(); Phone?phone2=new?Phone(); new?Thread(()->{ try?{ phone.sendEmail(); }?catch?(Exception?e)?{ //?TODO?Auto-generated?catch?block e.printStackTrace(); } },"A").start(); Thread.sleep(100); new?Thread(()->{ try?{ //phone.sendSMS(); //phone.sayHello(); phone2.sendSMS(); }?catch?(Exception?e)?{ //?TODO?Auto-generated?catch?block e.printStackTrace(); } },"B").start(); }}
Explanation: Here is an example. The monitor uses Its mobile phone law mail. I called on my own cell phone. Then it doesn't matter who comes first and who comes last.
5. Two static synchronization methods, the same mobile phone, please print the email or text message first
/*手機類可以發(fā)郵件和發(fā)短信*/class?Phone{ public?static?synchronized?void?sendEmail()?throws?Exception{ TimeUnit.SECONDS.sleep(4); //表示暫停4秒,它是一個枚舉類型 System.out.println("***sendEmail"); } public?static?synchronized?void?sendSMS()?throws?Exception{ System.out.println("***sendSMS"); } public?void?sayHello(){ System.out.println("***sayHello"); }}public?class?Lock8Demo?{ public?static?void?main(String[]?args)?throws?InterruptedException?{ //創(chuàng)建一個資源類 Phone?phone=new?Phone(); Phone?phone2=new?Phone(); new?Thread(()->{ try?{ phone.sendEmail(); }?catch?(Exception?e)?{ //?TODO?Auto-generated?catch?block e.printStackTrace(); } },"A").start(); Thread.sleep(100); new?Thread(()->{ try?{ phone.sendSMS(); //phone.sayHello(); //phone2.sendSMS(); }?catch?(Exception?e)?{ //?TODO?Auto-generated?catch?block e.printStackTrace(); } },"B").start(); }}
Explanation: It can be combined with question 6 Analysis
6. Two static synchronization methods, two mobile phones, please print the email or text message first
/*手機類可以發(fā)郵件和發(fā)短信*/class?Phone{ public?static?synchronized?void?sendEmail()?throws?Exception{ TimeUnit.SECONDS.sleep(4); //表示暫停4秒,它是一個枚舉類型 System.out.println("***sendEmail"); } public?static?synchronized?void?sendSMS()?throws?Exception{ System.out.println("***sendSMS"); } public?void?sayHello(){ System.out.println("***sayHello"); }}public?class?Lock8Demo?{ public?static?void?main(String[]?args)?throws?InterruptedException?{ //創(chuàng)建一個資源類 Phone?phone=new?Phone(); Phone?phone2=new?Phone(); new?Thread(()->{ try?{ phone.sendEmail(); }?catch?(Exception?e)?{ //?TODO?Auto-generated?catch?block e.printStackTrace(); } },"A").start(); Thread.sleep(100); new?Thread(()->{ try?{ //phone.sendSMS(); //phone.sayHello(); phone2.sendSMS(); }?catch?(Exception?e)?{ //?TODO?Auto-generated?catch?block e.printStackTrace(); } },"B").start(); }}
Analysis:
static Belongs to a class. In other words, he does not belong to an independent individual of the current object this. It is a global class. This requires considering the difference between object locks and global locks. Global locks are class locks. At this time, whether it is one phone or multiple phones, they all come from the same Phone class. No matter which object you lock now, I have to wait until it releases the lock before it can be used.
7.1 static synchronization method, 1 ordinary synchronization method, the same mobile phone, please print the email or text message first
/*手機類可以發(fā)郵件和發(fā)短信*/class?Phone{ public?static?synchronized?void?sendEmail()?throws?Exception{ TimeUnit.SECONDS.sleep(4); //表示暫停4秒,它是一個枚舉類型 System.out.println("***sendEmail"); } public?synchronized?void?sendSMS()?throws?Exception{ System.out.println("***sendSMS"); } public?void?sayHello(){ System.out.println("***sayHello"); }}public?class?Lock8Demo?{ public?static?void?main(String[]?args)?throws?InterruptedException?{ //創(chuàng)建一個資源類 Phone?phone=new?Phone(); Phone?phone2=new?Phone(); new?Thread(()->{ try?{ phone.sendEmail(); }?catch?(Exception?e)?{ //?TODO?Auto-generated?catch?block e.printStackTrace(); } },"A").start(); Thread.sleep(100); new?Thread(()->{ try?{ phone.sendSMS(); //phone.sayHello(); //phone2.sendSMS(); }?catch?(Exception?e)?{ //?TODO?Auto-generated?catch?block e.printStackTrace(); } },"B").start(); }}
One static, An ordinary one. The same phone is locked. The static method locks the Class. It is equivalent to us locking one school gate and one is an ordinary synchronization method, which locks the current object. For example, ordinary teachers. The objects of the lock are different. No conflict
8.1 static synchronization method, 1 normal synchronization method, two mobile phones, please print the email or text message first
/*手機類可以發(fā)郵件和發(fā)短信*/class?Phone{ public?static?synchronized?void?sendEmail()?throws?Exception{ TimeUnit.SECONDS.sleep(4); //表示暫停4秒,它是一個枚舉類型 System.out.println("***sendEmail"); } public?synchronized?void?sendSMS()?throws?Exception{ System.out.println("***sendSMS"); } public?void?sayHello(){ System.out.println("***sayHello"); }}public?class?Lock8Demo?{ public?static?void?main(String[]?args)?throws?InterruptedException?{ //創(chuàng)建一個資源類 Phone?phone=new?Phone(); Phone?phone2=new?Phone(); new?Thread(()->{ try?{ phone.sendEmail(); }?catch?(Exception?e)?{ //?TODO?Auto-generated?catch?block e.printStackTrace(); } },"A").start(); Thread.sleep(100); new?Thread(()->{ try?{ //phone.sendSMS(); //phone.sayHello(); phone2.sendSMS(); }?catch?(Exception?e)?{ //?TODO?Auto-generated?catch?block e.printStackTrace(); } },"B").start(); }}
Explanation: This is the same as above.
8 Lock Theory Explanation
1. If there are multiple synchronized methods in an object, as long as one thread calls one of the synchronized methods at a certain time, other threads can only wait. In other words, at a certain time, Only one thread can access these synchronized methods.
The current object this is locked. After being locked, other threads cannot enter other synchronized methods of the current object.
After adding a normal method, I found that it has nothing to do with the synchronization lock.
After exchanging the two objects, they no longer have the same lock, and the situation changes immediately.
After switching to static synchronization methods, the situation immediately changed
All non-static synchronization methods use the same lock ------ the instance object itself
2.synchronized realizes synchronization The basis of: Every object in Java can be used as a lock.
Specifically manifested in the following three forms:
- For ordinary synchronization methods, the lock is the current instance object
- For synchronization method blocks, the lock is the object configured in synchronized brackets.
For example, write
synchronized(this){
} - in the method. For static synchronization methods, the lock is the Class object of the current class.
When a process attempts to access a synchronized code block, it must first obtain the lock. Exiting or throwing an exception must release the lock.
That is to say, after the non-static synchronization method of an instance object acquires the lock, other non-static synchronization methods of the instance object must wait for the method that acquired the lock to release the lock before they can acquire the lock. However, because the non-static synchronization methods of other instance objects use different locks from the non-static synchronization methods of the instance object, they can acquire their own locks without waiting for the non-static synchronization method of the instance object that has acquired the lock to release the lock. .
All static synchronization methods also use the same lock-----the class object itself.
The two locks are two different objects, so there will be no race conditions between static synchronization methods and non-static synchronization methods. (Issue 78). That is, one lock class and one lock this, the two do not conflict.
But once a static synchronization method acquires the lock, other static synchronization methods must wait for the method to release the lock before they can acquire the lock. Regardless of whether it is between static methods of the same instance object or between static synchronization methods of different instance objects, as long as they are instance objects of the same class. (Question 56)
The above is the detailed content of Java introduces eight locks to help you thoroughly understand object locks and class locks. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

The settings.json file is located in the user-level or workspace-level path and is used to customize VSCode settings. 1. User-level path: Windows is C:\Users\\AppData\Roaming\Code\User\settings.json, macOS is /Users//Library/ApplicationSupport/Code/User/settings.json, Linux is /home//.config/Code/User/settings.json; 2. Workspace-level path: .vscode/settings in the project root directory

To correctly handle JDBC transactions, you must first turn off the automatic commit mode, then perform multiple operations, and finally commit or rollback according to the results; 1. Call conn.setAutoCommit(false) to start the transaction; 2. Execute multiple SQL operations, such as INSERT and UPDATE; 3. Call conn.commit() if all operations are successful, and call conn.rollback() if an exception occurs to ensure data consistency; at the same time, try-with-resources should be used to manage resources, properly handle exceptions and close connections to avoid connection leakage; in addition, it is recommended to use connection pools and set save points to achieve partial rollback, and keep transactions as short as possible to improve performance.

itertools.combinations is used to generate all non-repetitive combinations (order irrelevant) that selects a specified number of elements from the iterable object. Its usage includes: 1. Select 2 element combinations from the list, such as ('A','B'), ('A','C'), etc., to avoid repeated order; 2. Take 3 character combinations of strings, such as "abc" and "abd", which are suitable for subsequence generation; 3. Find the combinations where the sum of two numbers is equal to the target value, such as 1 5=6, simplify the double loop logic; the difference between combinations and arrangement lies in whether the order is important, combinations regard AB and BA as the same, while permutations are regarded as different;

DependencyInjection(DI)isadesignpatternwhereobjectsreceivedependenciesexternally,promotingloosecouplingandeasiertestingthroughconstructor,setter,orfieldinjection.2.SpringFrameworkusesannotationslike@Component,@Service,and@AutowiredwithJava-basedconfi

fixture is a function used to provide preset environment or data for tests. 1. Use the @pytest.fixture decorator to define fixture; 2. Inject fixture in parameter form in the test function; 3. Execute setup before yield, and then teardown; 4. Control scope through scope parameters, such as function, module, etc.; 5. Place the shared fixture in conftest.py to achieve cross-file sharing, thereby improving the maintainability and reusability of tests.

java.lang.OutOfMemoryError: Javaheapspace indicates insufficient heap memory, and needs to check the processing of large objects, memory leaks and heap settings, and locate and optimize the code through the heap dump analysis tool; 2. Metaspace errors are common in dynamic class generation or hot deployment due to excessive class metadata, and MaxMetaspaceSize should be restricted and class loading should be optimized; 3. Unabletocreatenewnativethread due to exhausting system thread resources, it is necessary to check the number of threads, use thread pools, and adjust the stack size; 4. GCoverheadlimitexceeded means that GC is frequent but has less recycling, and GC logs should be analyzed and optimized.

The core of mastering Advanced SpringDataJPA is to select the appropriate data access method based on the scenario and ensure performance and maintainability. 1. In custom query, @Query supports JPQL and native SQL, which is suitable for complex association and aggregation operations. It is recommended to use DTO or interface projection to perform type-safe mapping to avoid maintenance problems caused by using Object[]. 2. The paging operation needs to be implemented in combination with Pageable, but beware of N 1 query problems. You can preload the associated data through JOINFETCH or use projection to reduce entity loading, thereby improving performance. 3. For multi-condition dynamic queries, JpaSpecifica should be used

Use classes in the java.time package to replace the old Date and Calendar classes; 2. Get the current date and time through LocalDate, LocalDateTime and LocalTime; 3. Create a specific date and time using the of() method; 4. Use the plus/minus method to immutably increase and decrease the time; 5. Use ZonedDateTime and ZoneId to process the time zone; 6. Format and parse date strings through DateTimeFormatter; 7. Use Instant to be compatible with the old date types when necessary; date processing in modern Java should give priority to using java.timeAPI, which provides clear, immutable and linear
