Don't be tedious, let's get started!
1. Synchronization method for two threads accessing an object at the same time
Code:
public class SynchronizedObjectMethod implements Runnable { static SynchronizedObjectMethod instance = new SynchronizedObjectMethod(); @Override public void run() { method(); } public synchronized void method() { System.out.println("The method modifier form for object locks, which I call:" + Thread.currentThread().getName()); try { System.out.println(Thread.currentThread().getName() + " Hibernate for 3 seconds"); Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "End of run"); } public static void main(String[] args) { //Synchronization method for two threads accessing an object, an instance instance Thread t1 = new Thread(instance); Thread t2 = new Thread(instance); t1.start(); t2.start(); while (t1.isAlive() || t2.isAlive()) { } System.out.println("fininshed"); } }
Run result:
The method modifier form for object locks, which I call: Thread-0 Thread-0 Hibernate for 3 seconds Thread-0 End of run The method modifier form for object locks, which I call: Thread-1 Thread-1 Hibernate for 3 seconds Thread-1 End of run fininshed
Resolution: Need to contend for the same lock this, so execute sequentially.
2. Two threads access the synchronization method of two objects
Code:
public class SynchronizedTwoThreadToTwoObject implements Runnable { static SynchronizedTwoThreadToTwoObject instance1 = new SynchronizedTwoThreadToTwoObject(); static SynchronizedTwoThreadToTwoObject instance2 = new SynchronizedTwoThreadToTwoObject(); @Override public void run() { // Current object as lock synchronized (this) { System.out.println("I'm a block of code for object locks. My name is" + Thread.currentThread().getName()); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "End of run"); } } public static void main(String[] args) { //Two threads access the synchronization method of two objects, one instance1 and the other instance2 Thread t1 = new Thread(instance1); Thread t2 = new Thread(instance2); t1.start(); t2.start(); while (t1.isAlive() || t2.isAlive()) { } System.out.println("fininshed"); } }
Run result:
I'm a block of code for object locks. My name is Thread-0 I'm a block of code for object locks. My name is Thread-1 Thread-1 End of run Thread-0 End of run fininshed
Parsing: Parallel processing, no interference, lock instances are not the same.
3. Two threads access the static method of Synchronized
Code:
public class SynchronizedClassStatic implements Runnable { static SynchronizedClassStatic instance1=new SynchronizedClassStatic(); static SynchronizedClassStatic instance2=new SynchronizedClassStatic(); @Override public void run() { method(); } public static synchronized void method(){ System.out.println("I'm a form of class lock. My name is"+Thread.currentThread().getName()); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"Thread End"); } public static void main(String[] args){ //Static method for synchronized access by two threads Thread t1=new Thread(instance1); Thread t2=new Thread(instance2); t1.start(); t2.start(); while (t1.isAlive()||t2.isAlive()){ } System.out.println("fininshed"); } }
Run result:
I'm a form of class lock. My name is Thread-0 Thread-0 Thread End I'm a form of class lock. My name is Thread-1 Thread-1 Thread End fininshed
Resolution: The corresponding locks are executed one by one in the same order.
4. Access synchronous and asynchronous methods simultaneously
Code:
public class SynchronizedYesOrNo implements Runnable { static SynchronizedYesOrNo instance=new SynchronizedYesOrNo(); public static void main(String[] args) { Thread th1=new Thread(instance); Thread th2=new Thread(instance); th1.start(); th2.start(); while(th1.isAlive()||th2.isAlive()){ } System.out.println("finished"); } @Override public void run() { if(Thread.currentThread().getName().equals("Thread-0")){ method1(); }else{ method2(); } } public synchronized void method1(){ System.out.println("I added sync method"+Thread.currentThread().getName()); try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"End"); } public synchronized static void method2(){ System.out.println("Did I add a sync method?"+Thread.currentThread().getName()); try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"End"); } }
Run result:
I added sync method Thread-0 Did I add a sync method? Thread-1 Thread-0 End Thread-1 End finished
Resolution: Synchronous methods will not have concurrency problems, asynchronous methods will not be affected, and concurrency problems will occur.
5. Different common synchronization methods for accessing the same object
Code:
public class SynchronizedDifferentMethod implements Runnable { static SynchronizedDifferentMethod instance=new SynchronizedDifferentMethod(); @Override public void run() { if(Thread.currentThread().getName().equals("Thread-0")){ method1(); }else { method2(); } } public synchronized void method1(){ System.out.println("I'm the way to lock"+Thread.currentThread().getName()); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"End of thread execution"); } public synchronized void method2(){ System.out.println("I'm also the way to lock"+Thread.currentThread().getName()+"End of thread execution"); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"End of thread execution"); } public static void main(String[] args) throws InterruptedException{ Thread t1=new Thread(instance); Thread t2=new Thread(instance); t1.start(); t2.start(); while (t1.isAlive()||t2.isAlive()){} System.out.println("fininshed"); } }
Run result:
I'm the way to lock Thread-0 Thread-0 End of thread execution I'm also the way to lock Thread-1 End of thread execution Thread-1 End of thread execution fininshed
Parse: Get this lock, so it will still be affected, serial execution.
6. Access both static and non-static synchronized
Code:
public class SynchronizedStaticAndNormal implements Runnable { static SynchronizedStaticAndNormal instance=new SynchronizedStaticAndNormal(); @Override public void run() { if(Thread.currentThread().getName().equals("Thread-0")){ method1(); }else { method2(); } } public synchronized static void method1(){ System.out.println("I am the static method of locking 1 "+Thread.currentThread().getName()); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"End of thread execution"); } public synchronized void method2(){ System.out.println("I am the non-static method of locking 2 "+Thread.currentThread().getName()); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"End of thread execution"); } public static void main(String[] args) throws InterruptedException{ Thread t1=new Thread(instance); Thread t2=new Thread(instance); t1.start(); t2.start(); while (t1.isAlive()||t2.isAlive()){} System.out.println("fininshed"); } }
Run result:
I am the static method of locking 1 Thread-0 I am the non-static method of locking 2 Thread-1 Thread-1 End of thread execution Thread-0 End of thread execution fininshed
Resolution: method1 locks the.class object, method2 locks the this object, locks are different, no conflicts, parallel execution.
7. The lock will be released after the method throws an exception
Code:
public class SynchronizedException implements Runnable { static SynchronizedException instance = new SynchronizedException(); @Override public void run() { if (Thread.currentThread().getName().equals("Thread-0")) { method1(); } else { method2(); } } public synchronized void method1() { /* // Throw Exception System.out.println("I am the static method of locking 1 "+ Thread.currentThread().getName()"; try { Thread.sleep(3000); //When an exception is thrown, the JVM automatically releases the lock for you, instead of releasing the lock manually by itself. throw new Exception(); } catch (InterruptedException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + ""End of thread execution"; */ // Throw RuntimeException System.out.println("I am the static method of locking 1" + Thread.currentThread().getName()); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } //When an exception is thrown, the JVM automatically releases the lock for you, instead of releasing the lock manually by itself. throw new RuntimeException(); // System.out.println(Thread.currentThread().getName()+ "End of Thread Execution"); } public synchronized void method2() { System.out.println("I am also the non-static method of locking 2" + Thread.currentThread().getName()); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "End of thread execution"); } public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(instance); Thread t2 = new Thread(instance); t1.start(); t2.start(); while (t1.isAlive() || t2.isAlive()) { } System.out.println("fininshed"); } }
Run result:
I am the static method of locking 1 Thread-0 Exception in thread "Thread-0" java.lang.RuntimeException at com.interview.javabasic.thread.a0914.SynchronizedException.method1(SynchronizedException.java:50) at com.interview.javabasic.thread.a0914.SynchronizedException.run(SynchronizedException.java:16) at java.lang.Thread.run(Thread.java:748) I am also the non-static method of locking 2 Thread-1 Thread-1 End of thread execution fininshed
Resolution: The lock is released after the method throws an exception.
Summary:
- A lock can only be acquired by one thread at the same time, threads that do not get the lock must wait (corresponding to 1,5 questions)
- Each instance has its own lock, with no effect between different instances except when the lock object is *.class and synchronized modifies the static method, all objects share a single class lock (corresponding, 2, 3, 4, 6)
- Whether the method completes its normal execution or the method throws an exception, the lock is released.
- The synchronized method is currently entered, in which the method without the synchronized modification is called. Is it still thread-safe? (Not thread-safe, synchronized can be called by multiple threads at the same time.)
Reference article:
- (Synchronized) Seven specific cases of multithreaded access synchronization methods
- Seven scenarios for Java multithreaded access synchronization methods
Don't be tedious, end the article, suggest three series!