编辑
2020-03-28
编程语言
00
请注意,本文编写于 1275 天前,最后修改于 105 天前,其中某些信息可能已经过时。

目录

对象锁示例
类锁示例
对象锁和类锁不会干扰

最近发现synchronized锁的是什么?甚至有人认为synchronized锁的是代码??!这个我觉得还是很有必要通过实际的示例来说明synchronized锁的到底是什么。

根据获取的锁的分类:获取对象锁和获取类锁!

获取对象锁的两种用法

1、同步代码块(synchronized(this), synchronized(类实例对象)),锁是小括号()中的实例对象。 2、同步非静态方法(synchronized method),锁是当前对象的实例对象。

获取类锁的两种用法

1、同步代码块(synchronized(类.class)),锁是小括号()中的类对象,即Class对象。 2、同步静态方法(synchronized static method),锁是当前对象的类对象(Class对象)。

对象锁示例

看看这样一段代码:

SynchronizedDemo.java

java
package thread_study.synchronize; import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurrent.TimeUnit; public class SynchronizedDemo implements Runnable{ @Override public void run() { String threadName = Thread.currentThread().getName(); if(threadName.startsWith("A")){ async(); }else if(threadName.startsWith("B")){ syncObjectBlock(); }else if(threadName.startsWith("C")){ syncObjectMethod(); } } private void async() { try { System.out.println(Thread.currentThread().getName() + "_Async_Start:" + new SimpleDateFormat("mm:ss").format(new Date())); TimeUnit.SECONDS.sleep(1); System.out.println(Thread.currentThread().getName() + "_Async_End:" + new SimpleDateFormat("mm:ss").format(new Date())); } catch (InterruptedException e) { e.printStackTrace(); } } private synchronized void syncObjectMethod() { System.out.println(Thread.currentThread().getName() + "_SyncObjectMethod:" + new SimpleDateFormat("mm:ss").format(new Date())); try { System.out.println(Thread.currentThread().getName() + "_SyncObjectMethod_Start:" + new SimpleDateFormat("mm:ss").format(new Date())); TimeUnit.SECONDS.sleep(1); System.out.println(Thread.currentThread().getName() + "_SyncObjectMethod_End:" + new SimpleDateFormat("mm:ss").format(new Date())); } catch (InterruptedException e) { e.printStackTrace(); } } private void syncObjectBlock() { System.out.println(Thread.currentThread().getName() + "_SyncObjectBlock:" + new SimpleDateFormat("mm:ss").format(new Date())); synchronized (this){ try { System.out.println(Thread.currentThread().getName() + "_SyncObjectBlock_Start:" + new SimpleDateFormat("mm:ss").format(new Date())); TimeUnit.SECONDS.sleep(1); System.out.println(Thread.currentThread().getName() + "_SyncObjectBlock_End:" + new SimpleDateFormat("mm:ss").format(new Date())); } catch (InterruptedException e) { e.printStackTrace(); } } } }

SynchronizedMain.java

java
package thread_study.synchronize; public class SynchronizedMain { public static void main(String[] args) { SynchronizedDemo demo = new SynchronizedDemo(); Thread A_thread1 = new Thread(demo, "A_thread1"); Thread A_thread2 = new Thread(demo, "A_thread2"); Thread B_thread1 = new Thread(demo, "B_thread1"); Thread B_thread2 = new Thread(demo, "B_thread2"); Thread C_thread1 = new Thread(demo, "C_thread1"); Thread C_thread2 = new Thread(demo, "C_thread2"); A_thread1.start(); A_thread2.start(); B_thread1.start(); B_thread2.start(); C_thread1.start(); C_thread2.start(); } }

mark

但是如果我们传入不同的对象呢?

java
package thread_study.synchronize; public class SynchronizedMain { public static void main(String[] args) { //SynchronizedDemo demo = new SynchronizedDemo(); Thread A_thread1 = new Thread(new SynchronizedDemo(), "A_thread1"); Thread A_thread2 = new Thread(new SynchronizedDemo(), "A_thread2"); Thread B_thread1 = new Thread(new SynchronizedDemo(), "B_thread1"); Thread B_thread2 = new Thread(new SynchronizedDemo(), "B_thread2"); Thread C_thread1 = new Thread(new SynchronizedDemo(), "C_thread1"); Thread C_thread2 = new Thread(new SynchronizedDemo(), "C_thread2"); A_thread1.start(); A_thread2.start(); B_thread1.start(); B_thread2.start(); C_thread1.start(); C_thread2.start(); } }

mark

从上面的代码和结果中我们可以得出一个结论,那就是

获取对象锁的两种用法: 1、同步代码块(synchronized(this), synchronized(类实例对象)),锁是小括号()中的实例对象。 2、同步非静态方法(synchronized method),锁是当前对象的实例对象。

同步非静态方法锁住整个方法,而同步代码块只是锁住的只是方法中的一部分代码

获取类锁的两种用法 1、同步代码块(synchronized(类.class)),锁是小括号()中的类对象,即Class对象。 2、同步静态方法(synchronized static method),锁是当前对象的类对象(Class对象)。

同步静态方法锁住整个方法,而同步代码块只是锁住的只是方法中的一部分代码,与上面一样的

类锁示例

下面来看看同步静态方法和同步代码块(synchronized(类.class))的效果吧:

java
package thread_study.synchronize; import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurrent.TimeUnit; public class SynchronizedDemo implements Runnable{ @Override public void run() { String threadName = Thread.currentThread().getName(); if(threadName.startsWith("A")){ async(); }else if(threadName.startsWith("B")){ syncObjectBlock(); }else if(threadName.startsWith("C")){ syncObjectMethod(); }else if(threadName.startsWith("D")){ syncClassBlock(); }else if(threadName.startsWith("E")){ syncClassMethod(); } } private synchronized static void syncClassMethod() { System.out.println(Thread.currentThread().getName() + "_SyncClassMethod:" + new SimpleDateFormat("mm:ss").format(new Date())); try { System.out.println(Thread.currentThread().getName() + "_SyncClassMethod_Start:" + new SimpleDateFormat("mm:ss").format(new Date())); TimeUnit.SECONDS.sleep(1); System.out.println(Thread.currentThread().getName() + "_SyncClassMethod_End:" + new SimpleDateFormat("mm:ss").format(new Date())); } catch (InterruptedException e) { e.printStackTrace(); } } private void syncClassBlock() { System.out.println(Thread.currentThread().getName() + "_SyncClassBlock:" + new SimpleDateFormat("mm:ss").format(new Date())); synchronized (SynchronizedDemo.class){ try { System.out.println(Thread.currentThread().getName() + "_SyncClassBlock_Start:" + new SimpleDateFormat("mm:ss").format(new Date())); TimeUnit.SECONDS.sleep(1); System.out.println(Thread.currentThread().getName() + "_SyncClassBlock_End:" + new SimpleDateFormat("mm:ss").format(new Date())); } catch (InterruptedException e) { e.printStackTrace(); } } } private void async() { try { System.out.println(Thread.currentThread().getName() + "_Async_Start:" + new SimpleDateFormat("mm:ss").format(new Date())); TimeUnit.SECONDS.sleep(1); System.out.println(Thread.currentThread().getName() + "_Async_End:" + new SimpleDateFormat("mm:ss").format(new Date())); } catch (InterruptedException e) { e.printStackTrace(); } } //...和上面一样的 }

SynchronizedMain.java

java
package thread_study.synchronize; public class SynchronizedMain { public static void main(String[] args) { Thread A_thread1 = new Thread(new SynchronizedDemo(), "A_thread1"); Thread A_thread2 = new Thread(new SynchronizedDemo(), "A_thread2"); Thread D_thread1 = new Thread(new SynchronizedDemo(), "D_thread1"); Thread D_thread2 = new Thread(new SynchronizedDemo(), "D_thread2"); Thread E_thread1 = new Thread(new SynchronizedDemo(), "E_thread1"); Thread E_thread2 = new Thread(new SynchronizedDemo(), "E_thread2"); A_thread1.start(); A_thread2.start(); D_thread1.start(); D_thread2.start(); E_thread1.start(); E_thread2.start(); } }

mark

对象锁和类锁不会干扰

最后看看类锁和对象锁是否会相互影响呢?

修改一下代码:

java
package thread_study.synchronize; public class SynchronizedMain { public static void main(String[] args) { //SynchronizedDemo demo = new SynchronizedDemo(); Thread A_thread1 = new Thread(new SynchronizedDemo(), "A_thread1"); Thread A_thread2 = new Thread(new SynchronizedDemo(), "A_thread2"); Thread B_thread1 = new Thread(new SynchronizedDemo(), "B_thread1"); Thread B_thread2 = new Thread(new SynchronizedDemo(), "B_thread2"); Thread C_thread1 = new Thread(new SynchronizedDemo(), "C_thread1"); Thread C_thread2 = new Thread(new SynchronizedDemo(), "C_thread2"); Thread D_thread1 = new Thread(new SynchronizedDemo(), "D_thread1"); Thread D_thread2 = new Thread(new SynchronizedDemo(), "D_thread2"); Thread E_thread1 = new Thread(new SynchronizedDemo(), "E_thread1"); Thread E_thread2 = new Thread(new SynchronizedDemo(), "E_thread2"); A_thread1.start(); A_thread2.start(); B_thread1.start(); B_thread2.start(); C_thread1.start(); C_thread2.start(); D_thread1.start(); D_thread2.start(); E_thread1.start(); E_thread2.start(); } }

mark

可以看出来,类锁和对象锁是不会相互干扰的!

本文作者:Tim

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!