三个核心概念
- 原子性
- 可见性
- 顺序性
怎么保证原子性
- 锁
- synchronized
- cas。利用了CPU级别的CAS指令,由于是CPU级别的指令,其开销比需要操作系统参与的锁的开销小。
前两种方法原理一样,通过锁来实现资源的排它性。
使用锁,可以保证同一时间只有一个线程能拿到锁,也就保证了同一时间只有一个线程能执行申请锁和释放锁之间的代码。
public void testLock () {
lock.lock();
try{
int j = i;
i = j + 1;
} finally {
lock.unlock();
}
}
使用非静态同步方法时,锁住的是当前实例;使用静态同步方法时,锁住的是该类的Class对象;使用静态代码块时,锁住的是synchronized关键字后面括号内的对象。
public void testLock () {
synchronized (anyObject){
int j = i;
i = j + 1;
}
}
怎么保证可见性
volatile关键字可以保证可见性。当使用volatile修饰某个变量时,它会保证对该变量的修改会立即被更新到内存中,并且将其它缓存中对该变量的缓存设置成无效
怎么保证顺序性
jvm有一些隐式的原则保证顺序。 happens-before原则(先行发生原则)
- 传递规则:如果操作1在操作2前面,而操作2在操作3前面,则操作1肯定会在操作3前发生。
- 锁定规则:一个unlock操作肯定会在后面对同一个锁的lock操作前发生。
- volatile变量规则:对一个被volatile修饰的写操作先发生于后面对该变量的读操作。
- 程序次序规则:一个线程内,按照代码顺序执行
- 线程启动规则:Thread对象的start()方法先发生于此线程的其它动作
- 线程终结原则:线程的终止检测后发生于线程中其它的所有操作
- 线程中断规则: 对线程interrupt()方法的调用先发生于对该中断异常的获取
- 对象终结规则:一个对象构造先于它的finalize发生
网友评论