synchronized

  1. 修饰代码块:大括号括起来的代码,作用于调用的对象。
  2. 修饰方法:整个方法,作用于调用的对象。
  3. 修饰静态方法:整个静态方法,作用于所有对象。
  4. 修饰类:括号括起来的部分,作用于所有对象。

修饰代码块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public void synchronizedTest1(String type) {
synchronized (this) {
for (int i = 0; i < 10; i++) {
String s = String.format("test1 - %s: %s", type, i);
System.out.println(s);
}
}
}

//测试
public static void main(String[] args) {
SynchronizedExample synchronizedExample = new SynchronizedExample();
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(() -> {
synchronizedExample.synchronizedTest1("type1");
});

executorService.execute(() -> {
synchronizedExample.synchronizedTest1("type2");
});
}
// 输出结果:对于同步代码块,作用于同一个对象,会顺序的执行,
等待另一个线程执行完毕才可以执行
test1 - type1: 0
test1 - type1: 1
test1 - type1: 2
test1 - type1: 3
test1 - type1: 4
test1 - type1: 5
test1 - type1: 6
test1 - type1: 7
test1 - type1: 8
test1 - type1: 9
test1 - type2: 0
test1 - type2: 1
test1 - type2: 2
test1 - type2: 3
test1 - type2: 4
test1 - type2: 5
test1 - type2: 6
test1 - type2: 7
test1 - type2: 8
test1 - type2: 9

修饰方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public synchronized void synchronizedTest2(String type) {
for (int i = 0; i < 10; i++) {
String s = String.format("test1 - %s: %s", type, i);
System.out.println(s);
}
}

//测试
public static void main(String[] args) {
SynchronizedExample synchronizedExample = new SynchronizedExample();
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(() -> {
synchronizedExample.synchronizedTest2("type1");
});

executorService.execute(() -> {
synchronizedExample.synchronizedTest2("type2");
});
}

synchronized 关键字修饰代码块或方法都是作用于当前调用的对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// 测试
public static void main(String[] args) {
SynchronizedExample synchronizedExample1 = new SynchronizedExample();
SynchronizedExample synchronizedExample2 = new SynchronizedExample();

ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(() -> {
synchronizedExample1.synchronizedTest1("type1");
});

executorService.execute(() -> {
synchronizedExample2.synchronizedTest1("type2");
});
}

//测试结果:对于同步代码快,作用于不同的对象,执行时是互相不影响的。
test1 - type1: 0
test1 - type2: 0
test1 - type1: 1
test1 - type2: 1
test1 - type1: 2
test1 - type2: 2
test1 - type1: 3
test1 - type2: 3
test1 - type1: 4
test1 - type2: 4
test1 - type1: 5
test1 - type2: 5
test1 - type1: 6
test1 - type1: 7
test1 - type2: 6
test1 - type1: 8
test1 - type2: 7
test1 - type1: 9
test1 - type2: 8
test1 - type2: 9
  1. 当同步代码块修饰的时是一个方法中的所有的方法时是等同于修饰这个方法的。
  2. 子类继承父类时无法继承父类方法的synchronized关键字。

synchronized修饰静态方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public static synchronized void synchronizedTest1(String type) {
for (int i = 0; i < 10; i++) {
String s = String.format("test1 - %s: %s", type, i);
System.out.println(s);
}
}

//测试
public static void main(String[] args) {
SynchronizedExample synchronizedExample1 = new SynchronizedExample();
SynchronizedExample synchronizedExample2 = new SynchronizedExample();

ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(() -> {
synchronizedExample1.synchronizedTest1("type1");
});

executorService.execute(() -> {
synchronizedExample2.synchronizedTest1("type2");
});
}

// 测试结果: synchronized修饰静态方法的时候时作用于整个类的,即:使用不同的对象,但只要他们同属于一个synchronized类,就会同一个时间只会有一个线程在执行

test1 - type1: 0
test1 - type1: 1
test1 - type1: 2
test1 - type1: 3
test1 - type1: 4
test1 - type1: 5
test1 - type1: 6
test1 - type1: 7
test1 - type1: 8
test1 - type1: 9
test1 - type2: 0
test1 - type2: 1
test1 - type2: 2
test1 - type2: 3
test1 - type2: 4
test1 - type2: 5
test1 - type2: 6
test1 - type2: 7
test1 - type2: 8
test1 - type2: 9

synchronized修饰类

1
2
3
4
5
6
7
8
9
10

//synchronized修饰类和修饰静态方法一样,都会作用于整个类
public static void synchronizedTest1(String type) {
synchronized (SynchronizedExample.class) {
for (int i = 0; i < 10; i++) {
String s = String.format("test1 - %s: %s", type, i);
System.out.println(s);
}
}
}

synchronized: 是不可中断锁,适合竞争不激烈,可读性好。
LOCK:可中断锁,多样化同步,竞争激烈时能维持常态。
Atomic:竞争激烈时能维持常态,比Lock性能好;只能同步一个值。