-
- 锁一定是可重入的;
-
- 程序执行过程中,一旦遇到异常,锁立即释放;
锁省升级过程
synchronize加锁之后,现在对象markword上记录这个线程的id(偏向锁); 如果有其他线程争用,第二个线程自旋等待第一个线程使用完(自旋锁),自旋锁一直占用系统内存; 自旋10次之后升级为重量级锁,进入等待队列。
Volatile
public class T {
/*volatile*/ boolean running = true;
private void m() {
System.out.println("m start");
while (running) {
}
System.out.println("m end!");
}
public static void main(String[] args) {
T t = new T();
new Thread(t::m).start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
t.running = false;
}
}
- 保证线程可见性
- 线程有共享内存和工作内存,线程会先从共享内存中拷贝共享数据到工作内存,修改值之后写入共享内存,但是另一个内存什么时候去读,这个不好控制,线程之间不可见。
- 线程有共享内存和工作内存,线程会先从共享内存中拷贝共享数据到工作内存,修改值之后写入共享内存,但是另一个内存什么时候去读,这个不好控制,线程之间不可见。
- 禁止指令重排序
- 一个对象创建过程:先申请内存空间赋默认值;然后将需要的值赋给变量;最后实例指向内存地址。保证创建过程中不被其他线程访问。 volatile 不能保证原子性