线程的原子性
public class T00_IPlusPlus {
private static long n = 0L;
public static void main(String[] args) throws Exception {
Thread[] threads = new Thread[100];
CountDownLatch latch = new CountDownLatch(threads.length);
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(() -> {
for (int j = 0; j < 10000; j++) {
//synchronized (T00_IPlusPlus.class) {
n++;
//}
}
latch.countDown();
});
}
for (Thread t : threads) {
t.start();
}
latch.await();
System.out.println(n);
}
}
1.一些基本概念
race condition => 竞争条件 , 指的是多个线程访问共享数据的时候产生竞争
数据的不一致(unconsistency),并发访问之下产生的不期望出现的结果
如何保障数据一致呢?--> 线程同步(线程执行的顺序安排好),
monitor (管程) ---> 锁
critical section -> 临界区
如果临界区执行时间长,语句多,叫做 锁的粒度比较粗,反之,就是锁的粒度比较细
具体: 保障操作的原子性(Atomicity)
- 悲观的认为这个操作会被别的线程打断(悲观锁)synchronized(上一个小程序)
- 乐观的认为这个做不会被别的线程打断(乐观锁 自旋锁 无锁)cas操作 CAS = Compare And Set/Swap/Exchange
2.上锁的本质
(1)上锁的本质是把并发编程序列化
(2) 保障可见性注意序列化并非其他程序一直没机会执行,而是有可能会被调度,但是抢不到锁,又回到Blocked或者Waiting状态(sync锁升级)一定是锁定同一把锁
3.JVM中的两种锁
重量级锁(经过操作系统的调度)synchronized早期都是这种锁
轻量级锁(CAS的实现,不经过OS调度)(无锁 - 自旋锁 - 乐观锁)
4.两种锁的效率
不同的场景:
临界区执行时间比较长 , 等的人很多 -> 重量级
时间短,等的人少 -> 自旋锁