synchronized锁的是什么
最近发现synchronized锁的是什么?甚至有人认为synchronized锁的是代码??!这个我觉得还是很有必要通过实际的示例来说明synchronized锁的到底是什么。
根据获取的锁的分类:获取对象锁和获取类锁!
获取对象锁的两种用法
1、同步代码块(synchronized(this), synchronized(类实例对象)),锁是小括号()中的实例对象。 2、同步非静态方法(synchronized method),锁是当前对象的实例对象。
获取类锁的两种用法
1、同步代码块(synchronized(类.class)),锁是小括号()中的类对象,即Class对象。 2、同步静态方法(synchronized static method),锁是当前对象的类对象(Class对象)。
对象锁示例
看看这样一段代码:
SynchronizedDemo.java
1package thread_study.synchronize;
2
3import java.text.SimpleDateFormat;
4import java.util.Date;
5import java.util.concurrent.TimeUnit;
6
7public class SynchronizedDemo implements Runnable{
8
9 @Override
10 public void run() {
11 String threadName = Thread.currentThread().getName();
12 if(threadName.startsWith("A")){
13 async();
14 }else if(threadName.startsWith("B")){
15 syncObjectBlock();
16 }else if(threadName.startsWith("C")){
17 syncObjectMethod();
18 }
19 }
20
21 private void async() {
22 try {
23 System.out.println(Thread.currentThread().getName()
24 + "_Async_Start:"
25 + new SimpleDateFormat("mm:ss").format(new Date()));
26
27 TimeUnit.SECONDS.sleep(1);
28
29 System.out.println(Thread.currentThread().getName()
30 + "_Async_End:"
31 + new SimpleDateFormat("mm:ss").format(new Date()));
32
33 } catch (InterruptedException e) {
34 e.printStackTrace();
35 }
36 }
37 private synchronized void syncObjectMethod() {
38 System.out.println(Thread.currentThread().getName()
39 + "_SyncObjectMethod:"
40 + new SimpleDateFormat("mm:ss").format(new Date()));
41
42 try {
43 System.out.println(Thread.currentThread().getName()
44 + "_SyncObjectMethod_Start:"
45 + new SimpleDateFormat("mm:ss").format(new Date()));
46
47 TimeUnit.SECONDS.sleep(1);
48
49 System.out.println(Thread.currentThread().getName()
50 + "_SyncObjectMethod_End:"
51 + new SimpleDateFormat("mm:ss").format(new Date()));
52
53 } catch (InterruptedException e) {
54 e.printStackTrace();
55 }
56 }
57
58 private void syncObjectBlock() {
59 System.out.println(Thread.currentThread().getName()
60 + "_SyncObjectBlock:"
61 + new SimpleDateFormat("mm:ss").format(new Date()));
62 synchronized (this){
63 try {
64 System.out.println(Thread.currentThread().getName()
65 + "_SyncObjectBlock_Start:"
66 + new SimpleDateFormat("mm:ss").format(new Date()));
67
68 TimeUnit.SECONDS.sleep(1);
69
70 System.out.println(Thread.currentThread().getName()
71 + "_SyncObjectBlock_End:"
72 + new SimpleDateFormat("mm:ss").format(new Date()));
73 } catch (InterruptedException e) {
74 e.printStackTrace();
75 }
76 }
77 }
78}
SynchronizedMain.java
1package thread_study.synchronize;
2
3public class SynchronizedMain {
4 public static void main(String[] args) {
5 SynchronizedDemo demo = new SynchronizedDemo();
6 Thread A_thread1 = new Thread(demo, "A_thread1");
7 Thread A_thread2 = new Thread(demo, "A_thread2");
8 Thread B_thread1 = new Thread(demo, "B_thread1");
9 Thread B_thread2 = new Thread(demo, "B_thread2");
10 Thread C_thread1 = new Thread(demo, "C_thread1");
11 Thread C_thread2 = new Thread(demo, "C_thread2");
12 A_thread1.start();
13 A_thread2.start();
14
15 B_thread1.start();
16 B_thread2.start();
17
18 C_thread1.start();
19 C_thread2.start();
20 }
21}
但是如果我们传入不同的对象呢?
1package thread_study.synchronize;
2
3public class SynchronizedMain {
4 public static void main(String[] args) {
5 //SynchronizedDemo demo = new SynchronizedDemo();
6 Thread A_thread1 = new Thread(new SynchronizedDemo(), "A_thread1");
7 Thread A_thread2 = new Thread(new SynchronizedDemo(), "A_thread2");
8 Thread B_thread1 = new Thread(new SynchronizedDemo(), "B_thread1");
9 Thread B_thread2 = new Thread(new SynchronizedDemo(), "B_thread2");
10 Thread C_thread1 = new Thread(new SynchronizedDemo(), "C_thread1");
11 Thread C_thread2 = new Thread(new SynchronizedDemo(), "C_thread2");
12 A_thread1.start();
13 A_thread2.start();
14
15 B_thread1.start();
16 B_thread2.start();
17
18 C_thread1.start();
19 C_thread2.start();
20 }
21}
从上面的代码和结果中我们可以得出一个结论,那就是
获取对象锁的两种用法: 1、同步代码块(synchronized(this), synchronized(类实例对象)),锁是小括号()中的实例对象。 2、同步非静态方法(synchronized method),锁是当前对象的实例对象。
同步非静态方法锁住整个方法,而同步代码块只是锁住的只是方法中的一部分代码
获取类锁的两种用法 1、同步代码块(synchronized(类.class)),锁是小括号()中的类对象,即Class对象。 2、同步静态方法(synchronized static method),锁是当前对象的类对象(Class对象)。
同步静态方法锁住整个方法,而同步代码块只是锁住的只是方法中的一部分代码,与上面一样的
类锁示例
下面来看看同步静态方法和同步代码块(synchronized(类.class))的效果吧:
1package thread_study.synchronize;
2
3import java.text.SimpleDateFormat;
4import java.util.Date;
5import java.util.concurrent.TimeUnit;
6
7public class SynchronizedDemo implements Runnable{
8
9 @Override
10 public void run() {
11 String threadName = Thread.currentThread().getName();
12 if(threadName.startsWith("A")){
13 async();
14 }else if(threadName.startsWith("B")){
15 syncObjectBlock();
16 }else if(threadName.startsWith("C")){
17 syncObjectMethod();
18 }else if(threadName.startsWith("D")){
19 syncClassBlock();
20 }else if(threadName.startsWith("E")){
21 syncClassMethod();
22 }
23 }
24
25 private synchronized static void syncClassMethod() {
26 System.out.println(Thread.currentThread().getName()
27 + "_SyncClassMethod:"
28 + new SimpleDateFormat("mm:ss").format(new Date()));
29 try {
30 System.out.println(Thread.currentThread().getName()
31 + "_SyncClassMethod_Start:"
32 + new SimpleDateFormat("mm:ss").format(new Date()));
33 TimeUnit.SECONDS.sleep(1);
34 System.out.println(Thread.currentThread().getName()
35 + "_SyncClassMethod_End:"
36 + new SimpleDateFormat("mm:ss").format(new Date()));
37 } catch (InterruptedException e) {
38 e.printStackTrace();
39 }
40 }
41
42 private void syncClassBlock() {
43 System.out.println(Thread.currentThread().getName()
44 + "_SyncClassBlock:"
45 + new SimpleDateFormat("mm:ss").format(new Date()));
46 synchronized (SynchronizedDemo.class){
47 try {
48 System.out.println(Thread.currentThread().getName()
49 + "_SyncClassBlock_Start:"
50 + new SimpleDateFormat("mm:ss").format(new Date()));
51 TimeUnit.SECONDS.sleep(1);
52 System.out.println(Thread.currentThread().getName()
53 + "_SyncClassBlock_End:"
54 + new SimpleDateFormat("mm:ss").format(new Date()));
55 } catch (InterruptedException e) {
56 e.printStackTrace();
57 }
58 }
59 }
60
61 private void async() {
62 try {
63 System.out.println(Thread.currentThread().getName()
64 + "_Async_Start:"
65 + new SimpleDateFormat("mm:ss").format(new Date()));
66 TimeUnit.SECONDS.sleep(1);
67 System.out.println(Thread.currentThread().getName()
68 + "_Async_End:"
69 + new SimpleDateFormat("mm:ss").format(new Date()));
70 } catch (InterruptedException e) {
71 e.printStackTrace();
72 }
73 }
74 //...和上面一样的
75}
SynchronizedMain.java
1package thread_study.synchronize;
2
3public class SynchronizedMain {
4 public static void main(String[] args) {
5 Thread A_thread1 = new Thread(new SynchronizedDemo(), "A_thread1");
6 Thread A_thread2 = new Thread(new SynchronizedDemo(), "A_thread2");
7 Thread D_thread1 = new Thread(new SynchronizedDemo(), "D_thread1");
8 Thread D_thread2 = new Thread(new SynchronizedDemo(), "D_thread2");
9 Thread E_thread1 = new Thread(new SynchronizedDemo(), "E_thread1");
10 Thread E_thread2 = new Thread(new SynchronizedDemo(), "E_thread2");
11
12 A_thread1.start();
13 A_thread2.start();
14
15 D_thread1.start();
16 D_thread2.start();
17 E_thread1.start();
18 E_thread2.start();
19 }
20}
对象锁和类锁不会干扰
最后看看类锁和对象锁是否会相互影响呢?
修改一下代码:
1package thread_study.synchronize;
2
3public class SynchronizedMain {
4 public static void main(String[] args) {
5 //SynchronizedDemo demo = new SynchronizedDemo();
6 Thread A_thread1 = new Thread(new SynchronizedDemo(), "A_thread1");
7 Thread A_thread2 = new Thread(new SynchronizedDemo(), "A_thread2");
8 Thread B_thread1 = new Thread(new SynchronizedDemo(), "B_thread1");
9 Thread B_thread2 = new Thread(new SynchronizedDemo(), "B_thread2");
10 Thread C_thread1 = new Thread(new SynchronizedDemo(), "C_thread1");
11 Thread C_thread2 = new Thread(new SynchronizedDemo(), "C_thread2");
12 Thread D_thread1 = new Thread(new SynchronizedDemo(), "D_thread1");
13 Thread D_thread2 = new Thread(new SynchronizedDemo(), "D_thread2");
14 Thread E_thread1 = new Thread(new SynchronizedDemo(), "E_thread1");
15 Thread E_thread2 = new Thread(new SynchronizedDemo(), "E_thread2");
16
17 A_thread1.start();
18 A_thread2.start();
19
20 B_thread1.start();
21 B_thread2.start();
22 C_thread1.start();
23 C_thread2.start();
24
25 D_thread1.start();
26 D_thread2.start();
27 E_thread1.start();
28 E_thread2.start();
29 }
30}
可以看出来,类锁和对象锁是不会相互干扰的!