🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# This锁和Class锁 ## This锁 接下来代码理解一下This锁: ```java /** * @program: ThreadDemo * @description: This锁的实验 * @author: hs96.cn@Gmail.com * @create: 2020-09-06 */ public class SynchronizedThis { public static void main(String[] args) { ThisLock thisLock = new ThisLock(); new Thread("T1") { @Override public void run() { thisLock.m1(); } }.start(); new Thread("T2") { @Override public void run() { thisLock.m2(); } }.start(); } } class ThisLock { public synchronized void m1() { for (int i = 0; i <= 50; i++) { System.out.println(Thread.currentThread().getName()+i); try { Thread.sleep(2_000); } catch (InterruptedException e) { e.printStackTrace(); } } } public void m2() { for (int i = 0; i <= 50; i++) { System.out.println(Thread.currentThread().getName()+i); try { Thread.sleep(2_000); } catch (InterruptedException e) { e.printStackTrace(); } } } } ``` 这里我分别调用两个线程调用两个方法打印数字,线程一调用的方法我使用了同步方法,线程二调用的方法没做任何修饰,我们预期的结果是交替打印,因为只有方法一在抢锁,运行结果如下: ![](https://img.kancloud.cn/e2/9a/e29aeb14ef986bbdc569e1038eae4e6c_960x246.gif) 可以看到结果和我们预期的一样,两个线程交替执行了。 接下里我们把m2也加上synchronized,代码就不贴了运行效果如下: ![](https://img.kancloud.cn/93/2f/932f3a2d2f941f99b7bb7172d308964d_960x246.gif) 可以看到只有线程一执行了,这就说明synchronized修饰的这两个方法其实是使用的同一个锁,这个锁就是this锁。 接下来我们自己定义一个锁,然后让两个线程一个使用this锁一个使用我们定义的锁,代码如下: ```java /** * @program: ThreadDemo * @description: this锁 * @author: hs96.cn@Gmail.com * @create: 2020-09-06 */ public class SynchronizedThis { public static void main(String[] args) { ThisLock thisLock = new ThisLock(); new Thread("T1") { @Override public void run() { thisLock.m1(); } }.start(); new Thread("T2") { @Override public void run() { thisLock.m2(); } }.start(); } } class ThisLock { private final Object LOCK = new Object(); public synchronized void m1() { for (int i = 0; i <= 50; i++) { System.out.println(Thread.currentThread().getName()+i); try { Thread.sleep(1_000); } catch (InterruptedException e) { e.printStackTrace(); } } } public void m2() { synchronized (LOCK) { for (int i = 0; i <= 50; i++) { System.out.println(Thread.currentThread().getName() + i); try { Thread.sleep(2_000); } catch (InterruptedException e) { e.printStackTrace(); } } } } } ``` 运行效果如下: ![](https://img.kancloud.cn/5d/cb/5dcb86da112cbf34c79faa58420ed8f2_960x246.gif) 可以看到两个线程还是交替执行的,也就是我们自己定义的锁不是this锁。我们在把m1加上我们自己定义的锁: ```java public void m1() { synchronized (LOCK) { for (int i = 0; i <= 50; i++) { System.out.println(Thread.currentThread().getName() + i); try { Thread.sleep(1_000); } catch (InterruptedException e) { e.printStackTrace(); } } } } ``` 运行效果如下: ![](https://img.kancloud.cn/ea/2a/ea2ac910cff0dcd155576030b17b17d9_960x246.gif) 可以看到当两个线程同时使用我们定义的锁的时候,当m2抢到锁的时候,m1就在等待了。所以,同步锁要想让多线程执行的不同方法达到同步的效果则必须上的是同一把锁才行。 ## Class锁 跟This锁类似,Class锁顾名思议就是锁的一个类本身,而非类的实例,来看代码: ```java /** * @program: ThreadDemo * @description: 验证Class锁的存在 * @author: hs96.cn@Gmail.com * @create: 2020-09-06 */ public class SynchronizedStaticTest { public static void main(String[] args) { new Thread("T1") { @Override public void run() { SynchronizedStatic.m1(); } }.start(); new Thread("T2") { @Override public void run() { SynchronizedStatic.m2(); } }.start(); new Thread("T3") { @Override public void run() { SynchronizedStatic.m3(); } }.start(); } } ``` ```java /** * @program: ThreadDemo * @description: 验证Class锁的存在, 静态方法、静态代码块加的锁其实是Class锁。 * @author: hs96.cn@Gmail.com * @create: 2020-09-06 */ public class SynchronizedStatic { static { synchronized (SynchronizedStatic.class) { System.out.println("static " + Thread.currentThread().getName()); try { Thread.sleep(10_000); } catch (InterruptedException e) { e.printStackTrace(); } } } public synchronized static void m1() { System.out.println("m1 " + Thread.currentThread().getName()); try { Thread.sleep(10_000); } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized static void m2() { System.out.println("m2 " + Thread.currentThread().getName()); try { Thread.sleep(10_000); } catch (InterruptedException e) { e.printStackTrace(); } } public static void m3() { System.out.println("m3 " + Thread.currentThread().getName()); try { Thread.sleep(10_000); } catch (InterruptedException e) { e.printStackTrace(); } } } ``` 运行效果如下: ![](https://img.kancloud.cn/c4/a2/c4a29ba5449a178229423cb7b9171ddf_960x246.gif) 这里m1和m2抢同一个锁毫无疑问,但是可以看到执行完静态代码块之后,才能到静态方法。这就是class锁。