线程锁synchronized锁定的细节

线程锁synchronied的锁定小细节

线程锁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
67
68
69
70
71
72
73
74
75
/**
* Created by suomali on 2019/6/18.
*
* syn的锁定 方法锁 和块锁this差不多
* syn锁定范围 太大容易拖慢效率 小了容易锁定失败
*/
public class TrainBF2 {
public static void main(String[] args) {
SynTrain12306 synTrain = new SynTrain12306();
new Thread(synTrain,"小胡").start();
new Thread(synTrain,"小高").start();
}
}

class SynTrain12306 implements Runnable{

private Integer Tickets = 4;
private boolean flag = true;

@Override
public void run() {
while(flag){
test3();
}
}

public void test3(){ //双重check
if (Tickets <= 0) { //处理没票时的情况 如果没票了就都不用等了
flag = false;
return;
}
synchronized (this) {
if (Tickets <= 0) { //处理只剩下一张票的情况 都等在外边 但是当最后一张票被购买时就都不等了
flag = false;
return;
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "买到了票,还有" + --Tickets + "张票");
}
}


public void test2(){
synchronized (this) { //锁定面积大的块
if (Tickets <= 0) {
flag = false;
return;
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"买到了票,还有"+ --Tickets +"张票");
}

}
//直接锁定方法 使用这个方法的线程都需要等待
public synchronized void test(){
if(Tickets == 0){
flag = false;
return;
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"买到了票,还有"+ --Tickets +"张票");
}
}