Related free learning recommendations: java basic tutorial
8 Lock problem demonstration
1. Standard access
/*手机类可以发邮件和发短信*/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 { //创建一个资源类 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.
/*手机类可以发邮件和发短信*/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 { //创建一个资源类 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
/*手机类可以发邮件和发短信*/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 { //创建一个资源类 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
/*手机类可以发邮件和发短信*/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 { //创建一个资源类 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
/*手机类可以发邮件和发短信*/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 { //创建一个资源类 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
/*手机类可以发邮件和发短信*/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 { //创建一个资源类 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
/*手机类可以发邮件和发短信*/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 { //创建一个资源类 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
/*手机类可以发邮件和发短信*/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 { //创建一个资源类 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:
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!