java对象锁和类锁

it2026-05-13  1

synchronized修饰非静态方法,是对调用该方法的对象加锁,称为对象锁

synchronized修饰静态方法,是对该类加锁,称为类锁

每个对象的锁唯一

对象内所有加锁的非静态方法共用一把锁(即对象锁),一个加锁非静态方法执行,另一个加锁非静态方法就不能执行了,要等待持有锁的线程释放锁,不同对象之间的方法不互相作用。

类中的所有加锁的静态方法共用一把锁(即类锁),一个加锁的静态方法执行,同类另一个加锁静态方法就不能执行了,要等待持有锁的线程释放锁(对属于同一个类的两个对象的静态方法进行操作也会互斥执行)。

synchronized方法与synchronized代码块的区别:synchronized method(){}与synchronized(this){}之间没有什么区别。只是前者便于阅读理解,而后者可以更精确的控制冲突限制访问区域(粒度更小),锁的范围没有变,锁住的时间变短了因而性能更好。

加对象锁和加类锁之间互不相干,执行时候没有影响。

加锁方法的执行不会影响类/对象中未加锁的方法的执行。

对于synchronized(非this对象):

在多个线程持有“对象监视器”为同一对象的前提下,同一时间只有一个线程可以执行synchronized(非this对象)同步代码块里的代码。

在多个线程持有“对象监视器”不是同一对象,同一时间synchronized(非this对象)同步代码块里的代码异步执行,互不影响。

synchronized(非this对象)与synchronized方法异步执行,互不影响。

synchronized(a)与synchronized(b)方法异步执行,互不影响。

全部代码如下:

package suo; class Suo{ String s = new String(); String s1 = new String(); synchronized void fun1() throws InterruptedException{ System.out.println("加锁的非静态方法1开始执行"); Thread.sleep(2000); System.out.println("加锁的非静态方法1执行结束"); } synchronized void fun2() throws InterruptedException{ System.out.println("加锁的非静态方法2开始执行"); Thread.sleep(2000); System.out.println("加锁的非静态方法2执行结束"); } void fun5() throws InterruptedException{ synchronized (this) { System.out.println("加锁的非静态方法5开始执行"); Thread.sleep(2000); System.out.println("加锁的非静态方法5执行结束"); } } synchronized static void fun3() throws InterruptedException{ System.out.println("加锁的静态方法3开始执行"); Thread.sleep(2000); System.out.println("加锁的静态方法3执行结束"); } synchronized static void fun4() throws InterruptedException{ System.out.println("加锁的静态方法4开始执行"); Thread.sleep(2000); System.out.println("加锁的静态方法4执行结束"); } static void fun6() throws InterruptedException{ synchronized (Suo.class) { System.out.println("加锁的静态方法6开始执行"); Thread.sleep(2000); System.out.println("加锁的静态方法6执行结束"); } } void fun7(Integer i) throws InterruptedException{ // String s = new String(); synchronized (s) { System.out.println("非静态方法7开始执行(i代表非this对象) "+i); Thread.sleep(2000); System.out.println("非静态方法7执行结束(i代表非this对象) "+i); } } void fun11(Integer i) throws InterruptedException{ // String s = new String(); synchronized (s1) { System.out.println("非静态方法11开始执行(非this对象) "+i); Thread.sleep(2000); System.out.println("非静态方法11执行结束(非this对象) "+i); } } void fun8(Integer i) throws InterruptedException{ String s = new String(); synchronized (s) { System.out.println("非静态方法8开始执行(非this对象) "+i); Thread.sleep(2000); System.out.println("非静态方法8执行结束(非this对象) "+i); } } void fun10(Integer i) throws InterruptedException{ String s = new String(); synchronized (s) { System.out.println("非静态方法10开始执行(非this对象) "+i); Thread.sleep(2000); System.out.println("非静态方法10执行结束(非this对象) "+i); } } void fun9(int i) throws InterruptedException{ //synchronized (s1) { System.out.println("未加锁方法9开始执行 " + i); Thread.sleep(2000); System.out.println("未加锁方法9执行结束 " + i); //} } } public class TestSuo { public static void main(String[] args) { Suo suo1 = new Suo(); Suo suo2 = new Suo(); Thread thread1 = new Thread(new Runnable() { @Override public void run() { try { suo1.fun7(1); } catch (InterruptedException e) { e.printStackTrace(); } } }); Thread thread2 = new Thread(new Runnable() { @Override public void run() { try { suo1.fun1(); } catch (InterruptedException e) { e.printStackTrace(); } } }); thread1.start(); thread2.start(); // new Thread(new Runnable() { // // @Override // public void run() { // // // } // }).start(); } }

 

详细解释如下:

对象锁的两种实现方式:

类锁的两种实现方式:

synchronized方法与synchronized代码块的区别:synchronized method(){}与synchronized(this){}之间没有什么区别。只是前者便于阅读理解,而后者可以更精确的控制冲突限制访问区域(粒度更小),锁的范围没有变,锁住的时间变短了因而性能更好


对象内所有加锁的非静态方法共用一把锁(即对象锁),一个加锁非静态方法执行,另一个加锁非静态方法就不能执行了,要等待持有锁的线程释放锁,不同对象之间的方法不互相作用。


类中的所有加锁的静态方法共用一把锁(即类锁),一个加锁的静态方法执行,同类另一个加锁静态方法就不能执行了,要等待持有锁的线程释放锁(对属于同一个类的两个对象的静态方法进行操作也会互斥执行)。


加对象锁和加类锁之间互不相干,执行时候没有影响。


加锁方法的执行不会影响类/对象中未加锁的方法的执行。



对于synchronized(非this对象):

在多个线程持有“对象监视器”为同一对象的前提下,同一时间只有一个线程可以执行synchronized(非this对象)同步代码块里的代码。


在多个线程持有“对象监视器”不是同一对象,同一时间synchronized(非this对象)同步代码块里的代码异步执行,互不影响。


synchronized(非this对象)与synchronized方法异步执行,互不影响。


synchronized(a)与synchronized(b)方法异步执行,互不影响。

 

 

 

最新回复(0)