学习视频参考
偏向锁撤销情景
- 调用 hashCode
- 调用waitNotify
- 多线程访问【升级为轻量级锁,要先撤销偏向锁】
锁消除和锁粗化
消除的 话,会对代码进行逃逸分析【局部变量加锁】
每个对象一开始都是无锁的,随着线程间争夺锁,越激烈,锁的级别越高,并且锁只能升级不能降级。
什么是线程安全问题? Synchronized 底层实现
作者:牛客636793145号
链接:https://www.nowcoder.com/discuss/650653
来源:牛客网
sycnronized的作用
- 原子性:synchronized保证语句块内操作是原子的
- 可见性:synchronized保证可见性(通过“在执行unlock之前,必须先把此变量同步回主内存”实现)
- 有序性:synchronized保证有序性(通过“一个变量在同一时刻只允许一条线程对其进行lock操作”)
可以答,monitor enter 和 monitor exit
wait/notify原理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public class CyclicBarrierTest {
static Object lock = new Object();
public static void main(String[] args) throws InterruptedException {
lock.wait();
}
}
Exception in thread "main" java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:502)
at CyclicBarrierTest.main(CyclicBarrierTest.java:11)
Process finished with exit code 1
|
注意; wait 只能 在 syncrhonized代码块里面使用,不然报错
也就是说, 我在占有锁的时候 ,发现不应该由我占有锁,我可以用 wait 让给别人
sleep和 wait 区别
sleep 是 Thread 的静态方法, wait 是所有对象都有的
wait 它需要获得对象锁
reentrantLock 的基本使用
reentrantLock 可以被打断的
可以用 lockInterruptly方法实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
static Lock lock = new ReentrantLock();
public static void main(String[] args) {
Thread t = new Thread(()-> {
try {
//如果有竞争,就会进入阻塞队列等待
lock.lockInterruptibly();
System.out.println("往下执行后序逻辑");
} catch (InterruptedException e) {
// e.printStackTrace();
System.out.println("被打断了,没有继续往下执行");
}finally {
lock.unlock();
}
});
lock.lock();//先获取锁
t.start();
//打断
t.interrupt();
System.out.println("---");
}
|
wait/notify 固定线程顺序
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
|
static Object lock = new Object();
static boolean t1OK = false;
static boolean t2OK = false;
static boolean t3OK = false;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
synchronized (lock) {
System.out.println("t1");
t1OK = true;
lock.notifyAll();
}
});
Thread t2 = new Thread(() -> {
synchronized (lock) {
while (t1OK == false) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("t2");
t2OK = true;
lock.notifyAll();
}
});
Thread t3 = new Thread(() -> {
synchronized (lock) {
while (t2OK == false) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("t3");
t3OK = true;
}
});
t3.start();
t2.start();
t1.start();
// synchronized (lock) {
// // lock.wait(1000);
// }
}
|