Java-synchronized

在Java中,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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
public class Text {

public static void main(String[] args){
Sync sync = new Sync();
for (int i =0 ;i<3;i++){
// MyThread thread = new MyThread();
// 如果每个线程中都new了一个Sync类的对象,也就是产生了三个Sync对象,
// 由于不是同一个对象,所以可以多线程同时运行synchronized方法或代码段。
// 如果非要创建多个对象,可以让synchronized锁这个类对应的Class对象。
// 也就是 synchronized(Sync.class) 实现全局锁的效果。

// 在这里,使用同一个 sync 对象,就可以 synchronized (this){} 锁住了。
MyThread thread = new MyThread(sync);
thread.start();
}
}

static class MyThread extends Thread{
private Sync sync;

public MyThread(Sync sync){
this.sync = sync;
}

public MyThread(){

}

@Override
public void run() {
if (sync == null){
sync = new Sync();
}
sync.text();
}
}

static class Sync{
// 在用synchronized关键字的时候,
// 能缩小代码段的范围就尽量缩小,能在代码段上加同步就不要再整个方法上加同步。
// 这叫减小锁的粒度,使代码更大程度的并发。
public void text(){
// synchronized(this)以及非static的synchronized方法,
// 只能防止多个线程同时执行 "同一个对象" 的同步代码段。

// synchronized锁住的是括号里的对象,而不是代码。
// 对于非static的synchronized方法,锁的就是对象本身也就是this。

// 关于static synchronized方法,
// static方法可以直接类名加方法名调用,方法中无法使用this,
// 所以它锁的不是this,而是类的Class对象,
// 所以,static synchronized方法也相当于全局锁,相当于锁住了代码段。
synchronized (this){
System.out.println("开始");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("结束");
}
}
}

}