【Java】01-Java锁
锁
序号 | 锁类型 | 应用 |
---|---|---|
1 | 乐观锁 | CAS |
2 | 悲观锁 | synchronized, vector, hashtable |
3 | 自旋锁 | CAS |
4 | 可重入锁 | synchronized, Reentrantlock, Lock |
5 | 读写锁 | ReentrantReadWriteLock, CopyOnWriteArrayList, CopyOnWriteArraySet |
6 | 公平锁 | Reentrantlock(true) |
7 | 非公平锁 | synchronized, reentrantlock(false) |
8 | 共享锁 | ReentrantReadWriteLock中的读锁 |
9 | 独占锁 | synchronized, vector, hashtable, ReentrantReadWriteLock中的写锁 |
10 | 重量级锁 | synchronized |
11 | 轻量级锁 | 锁优化技术 |
12 | 偏向锁 | 锁优化技术 |
13 | 分段所 | ConcurrentHashMap |
14 | 互斥锁 | synchronized |
15 | 同步锁 | synchronized |
16 | 死锁 | 互相请求对方的资源 |
17 | 锁粗化 | 锁优化技术 |
18 | 锁消除 | 锁优化技术 |
乐观锁
CAS(compare and swap / compare and set)
CAS:无锁,自旋锁,乐观锁,轻量级锁。
线程不会出现阻塞,不会切换线程调度,切换上下文,恢复上下文。
Cas.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19public class CAS {
private AtomicInteger num = new AtomicInteger(0);
public Integer get() {
return num.get();
}
public void add() {
while (true) {
int oldValue = num.get();
int newValue = oldValue + 1;
if (num.compareAndSet(oldValue, newValue)) {
break;
}
}
}
}Main.java
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
30public class Main {
public static void main(String[] args) throws InterruptedException {
CAS number = new CAS();
long start = System.currentTimeMillis();
Thread t1 = new Thread(() -> {
for (int i = 0; i < 10000000; i++) {
number.add();
}
});
t1.start();
Thread t2 = new Thread(() -> {
for (int i = 0; i < 10000000; i++) {
number.add();
}
});
t2.start();
t1.join();
t2.join();
long end = System.currentTimeMillis();
System.out.println(end - start);
System.out.println(number.get());
}
}
问题
原子性
底层调用
1
public final native boolean compareAndSetInt(Object var1, long var2, int var4, int var5);
底层调用的C代码
1
2
3
4
5
6UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x))
UnsafeWraper("Unsafe_CompareAndSwapInt");
oop p = JNIHandles::resolve(obj);
jint* addr = (jint *) index_oop_from_field_offset_long(p, offset);
return (jint)(Atomic::cmpxchg(x, addr, e)) == e;
UNSAFE_ENDAtomic::cmpxchg(x, addr, e)
方法中重要的两条汇编指令lock
cmpxchgq
: compare and exchange
ABA问题
引入版本号,每次修改值之后,改变版本号。
CAS.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20public class CAS {
private final AtomicStampedReference<Integer> num = new AtomicStampedReference<>(0, 0);
public Integer get() {
return num.getReference();
}
public void add() {
while (true) {
int stamp = num.getStamp();
Integer reference = num.getReference();
boolean flag = num.compareAndSet(reference, reference + 1, stamp, stamp + 1);
if (flag) {
break;
}
}
}
}AtomicStampedReference
: 带有版本号的CAS类。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21// initialRef: 初始值
// initialStamp: 初始版本号
public AtomicStampedReference(V initialRef, int initialStamp) {
this.pair = AtomicStampedReference.Pair.of(initialRef, initialStamp);
}
// reference: 变量值
// stamp: 版本号
private static class Pair<T> {
final T reference;
final int stamp;
private Pair(T reference, int stamp) {
this.reference = reference;
this.stamp = stamp;
}
static <T> AtomicStampedReference.Pair<T> of(T reference, int stamp) {
return new AtomicStampedReference.Pair(reference, stamp);
}
}
悲观锁
自旋锁
可重入锁
读写锁
-------------本文结束感谢您的阅读-------------
相关文章