A-A+
Java-Synchronized用法(2)
Synchronized主要有以下几种用法:
1. 加在方法上:这里包括加在实例方法上、加在静态方法上。
2. 方法块:这里包括锁定this、锁定Class、锁定实例对象、锁定静态对象。
今天主要通过例子演示一下第二个用法:锁定this和锁定class。
首先是锁定this
测试代码如下:
1package com.xnck.example.sbtest;
2
3import org.junit.Test;
4
5public class ThreadTest {
6
7 public void printThisBlock(String input) {
8 synchronized (this) {
9 System.out.println(input + System.currentTimeMillis());
10 try {
11 Thread.sleep(3000);
12 } catch (InterruptedException e) {
13 e.printStackTrace();
14 }
15 System.out.println("3秒后的" + input + System.currentTimeMillis());
16 }
17 }
18
19 //region 测试方法
20
21 /**
22 * 锁定普通代码块,相同对象调用等待
23 */
24 @Test
25 public void test4() {
26 final ThreadTest test = new ThreadTest();
27
28 new Thread(new Runnable() {
29 @Override
30 public void run() {
31 System.out.println("第一个线程已启动" + System.currentTimeMillis());
32 test.printThisBlock("我是第一个线程");
33 }
34 }).start();
35
36 new Thread(new Runnable() {
37 @Override
38 public void run() {
39 System.out.println("第二个线程已启动" + System.currentTimeMillis());
40 test.printThisBlock("我是第二个线程");
41 }
42 }).start();
43 }
44
45 /**
46 * 锁定普通代码块,不同对象调用不需要等待
47 */
48 @Test
49 public void test5() {
50 final ThreadTest test1 = new ThreadTest();
51 final ThreadTest test2 = new ThreadTest();
52
53 new Thread(new Runnable() {
54 @Override
55 public void run() {
56 System.out.println("第一个线程已启动" + System.currentTimeMillis());
57 test1.printThisBlock("我是第一个线程");
58 }
59 }).start();
60
61 new Thread(new Runnable() {
62 @Override
63 public void run() {
64 System.out.println("第二个线程已启动" + System.currentTimeMillis());
65 test2.printThisBlock("我是第二个线程");
66 }
67 }).start();
68 }
69
70 //endregion
71}
测试结果如下:

锁定this,同一个对象,被调用时等待

锁定this,不同对象,调用时不需要等待
然后是锁定class
测试代码如下:
1package com.xnck.example.sbtest;
2
3import org.junit.Test;
4
5import java.util.Scanner;
6
7public class ThreadTest {
8
9 public void printStaticBlock(String input) {
10 synchronized (ThreadTest.class) {
11 System.out.println(input + System.currentTimeMillis());
12 try {
13 Thread.sleep(3000);
14 } catch (InterruptedException e) {
15 e.printStackTrace();
16 }
17 System.out.println("3秒后的" + input + System.currentTimeMillis());
18 }
19 }
20
21 private void waitToQuite() {
22 new Scanner(System.in).next();
23 }
24
25 //region 测试方法
26
27 /**
28 * 锁定静态代码块,相同对象调用需要等待
29 */
30 @Test
31 public void test6() {
32
33 final ThreadTest test1 = new ThreadTest();
34
35 new Thread(() -> {
36 System.out.println("第一个线程已启动" + System.currentTimeMillis());
37 test1.printStaticBlock("我是第一个线程");
38 }).start();
39
40 new Thread(() -> {
41 System.out.println("第二个线程已启动" + System.currentTimeMillis());
42 test1.printStaticBlock("我是第二个线程");
43 }).start();
44
45 waitToQuite();
46 }
47
48 /**
49 * 锁定静态代码块,不同对象调用需要等待
50 */
51 @Test
52 public void test7() {
53
54 final ThreadTest test1 = new ThreadTest();
55 final ThreadTest test2 = new ThreadTest();
56
57 new Thread(() -> {
58 System.out.println("第一个线程已启动" + System.currentTimeMillis());
59 test1.printStaticBlock("我是第一个线程");
60 }).start();
61
62 new Thread(() -> {
63 System.out.println("第二个线程已启动" + System.currentTimeMillis());
64 test2.printStaticBlock("我是第二个线程");
65 }).start();
66
67 waitToQuite();
68 }
69
70 //endregion
71}
测试结果如下:

锁定静态代码块,相同对象调用需要等待

锁定静态代码块,不同对象调用需要等待
