Open Draymonders opened 3 years ago
由此也明晰了,占有锁的是,线程对象,
public class SyncRetry {
private final Object monitor = new Object();
private Object connection = new Object();
private synchronized void validateConnection(int id) {
System.out.println("id: " + id + " enter");
synchronized (this.monitor) {
System.out.println("id: " + id + " try to reset connection");
if (this.connection != null) {
resetConnection(id);
}
}
}
private synchronized void resetConnection(int id) {
synchronized (this.monitor) {
if (this.connection != null) {
this.connection = null;
System.out.println("id: " + id + " reset the connection");
}
}
}
private synchronized void loopEnter(int id, int cnt) {
if (cnt > 10) {
return;
}
System.out.println("id: " + id + " loop cnt: " + cnt);
loopEnter(id, cnt + 1);
}
public static void main(String[] args) throws InterruptedException {
List<Thread> threads = new ArrayList<>();
SyncRetry syncRetry = new SyncRetry();
IntStream.range(0, 5).forEach(id -> {
threads.add(new Thread(() -> {
// syncRetry.validateConnection(id);
syncRetry.loopEnter(id, 0);
}));
});
for (Thread thread : threads) {
thread.start();
}
for (Thread thread : threads) {
thread.join();
}
}
}
执行结果
id: 0 loop cnt: 0
id: 0 loop cnt: 1
id: 0 loop cnt: 2
id: 0 loop cnt: 3
id: 0 loop cnt: 4
id: 0 loop cnt: 5
id: 0 loop cnt: 6
id: 0 loop cnt: 7
id: 0 loop cnt: 8
id: 0 loop cnt: 9
id: 0 loop cnt: 10
id: 4 loop cnt: 0
id: 4 loop cnt: 1
id: 4 loop cnt: 2
id: 4 loop cnt: 3
id: 4 loop cnt: 4
id: 4 loop cnt: 5
id: 4 loop cnt: 6
id: 4 loop cnt: 7
id: 4 loop cnt: 8
id: 4 loop cnt: 9
id: 4 loop cnt: 10
id: 3 loop cnt: 0
id: 3 loop cnt: 1
id: 3 loop cnt: 2
id: 3 loop cnt: 3
id: 3 loop cnt: 4
id: 3 loop cnt: 5
id: 3 loop cnt: 6
id: 3 loop cnt: 7
id: 3 loop cnt: 8
id: 3 loop cnt: 9
id: 3 loop cnt: 10
id: 2 loop cnt: 0
id: 2 loop cnt: 1
id: 2 loop cnt: 2
id: 2 loop cnt: 3
id: 2 loop cnt: 4
id: 2 loop cnt: 5
id: 2 loop cnt: 6
id: 2 loop cnt: 7
id: 2 loop cnt: 8
id: 2 loop cnt: 9
id: 2 loop cnt: 10
id: 1 loop cnt: 0
id: 1 loop cnt: 1
id: 1 loop cnt: 2
id: 1 loop cnt: 3
id: 1 loop cnt: 4
id: 1 loop cnt: 5
id: 1 loop cnt: 6
id: 1 loop cnt: 7
id: 1 loop cnt: 8
id: 1 loop cnt: 9
id: 1 loop cnt: 10
亚权总结: synchronize的实现原理是有一个lock对象,保留有线程的id 和锁的status,通过判断status 和id。
同样的线程再次sync时,先check lock对象的id,若同,则status 加1。
注意由于synchronized是基于monitor实现的,因此每次重入,monitor中的计数器仍会加1。
很久没用多线程了,包括多线程也没遇到那种资源互斥的情况,所以对锁的知识也就渐渐淡忘了。
今天阅读RedisLettuce的源码,发现sync可重入。刚开始还有点儿怀疑,便自己写了一个demo
执行结果