잠금 분산 : 단일 노드 레디 스를 달성하기 위해

스레드 간의 첫째, 동시성

우리는 두 개의 스레드 동기화 실행하려는 경우, 당신은 단지 sychronzied 또는 동일한 JVM 동기화 프로세스 내에서 여러 스레드의 이행을 보장하기 위해 Reetrantlock 클래스를 사용하여 추가해야합니다.

그래서 만약이 시스템은 예를 들어, 배포됩니다 스레드를 동시에 그것을 수행하는 방법에 희망을 실행하는 두 서버에?

그리고 우리가 달성하고자하는 것입니다이 하위 서브 드롭한다 :

사실, 가장 중요한 획득하고 잠금을 해제, 잠금 장치의 작동을위한 것입니다.

두 달성 레디 스

1, 잠금

set(key,线程的id,30,NX)

잠금은 레디 스에 데이터를 배치함으로써 달성된다,이 설정 방법 : 현재이 아닌이 키를 레디 스, 0이 반환되는 경우 1을 반환합니다. 당신이 할 수있는이 방법. 다른 스레드 간의 제어 동시성, 취득 잠금 생각이 메서드가 반환 한의 구현에 설정 방법.

후자의 두 매개 변수는 설정 만료 시간입니다. 당신은 설정하지 않으면 어떻게됩니까? 예를 들어, 스레드 A는 잠금, 다음 프로그램이 다른 스레드 서버는 잠금을받지 않습니다, 잠금이 해제되지되었습니다 사망 실패를 얻습니다. : 그래서, 의미의 만료 시간을 설정 잠금 설정을 얻을 수있는 다른 스레드에 영향을주지 않습니다 잠금 해제입니다 (물론, 당신은 메모리 레디 스 좋은 제거 메커니즘을 설정할) 만료일에 도달 한 후, 데이터가 자동으로 취소됩니다 .

몇몇은)는 :(는 다음 의사 코드입니다 달성 할 수 있다고

setnx(key,1)
expire(key,30)

레디 스 달성이 두 명령을 사용하지 : 대답은 NO입니다

우리는 프로세스가 잠겨 있는지 확인해야 원자 작업을 예를 들어, (키, 1) 후 setnx를 실행 한 후 클라이언트 스레드 A의 끝은 잠금이 또 다른 스레드에 의해 인수되지 않으며, 죽었어요.

2, 잠금이 해제됩니다

스레드가 동기 부호 블록의 완료 후에 수행되고, 수행 잠금 해제

del(key)

이 방법은 괜찮습니다? NO, NO, NO. 당연하지

이것을 고려 : 만료 날짜가 현재 30 초 동안 설정되어있는 경우, 실행 스레드 A 후 컨텐츠 동기화 코드 블록에 잠겨 얻을, 30 초 후에, 레디 스 제거 키를 넣어 시간을보고, 이 잠금을 해제 통지를하지 레디 스 (잠금이 해제되고,이 시간은은은, 아직 끝나지 스레드 BSET 그래서 조금 발견 당신이 쾌적한 플레이 잠금, 스레드 B를 얻을 수 있지만, 이번에는 그것이이 이상 실행 스레드 실행하지 못했습니다 ),이 사람이 그가 여전히 다음이 시간을 출시, 그것을 고정 된 생각, 잠금 스레드 B는 제거 된, 키가 제거 잠금을 모르는이 사람이다. 이러한 방법으로 동시성의 문제가있다. cuckolded되고처럼 나도 같은 몰라요.

우리는 (: + ID가 고유 서버 스레드 = 값을 식별 개인적인 생각이다) 스레드 ID에 저장된 값 세트를 설정할 수 있습니다

加锁:
String threadId = Thread.currentThread().getId()
set(key,threadId ,30,NX)

解锁:
if(threadId .equals(redisClient.get(key))){
del(key)
}

그러나 잠금 해제는 원자 작동하지 않습니다, 문제가 나타났다. 나는 아 문제가 될 것입니다 거기에 의존하고 있습니다.

이 같은 시나리오를 살펴 보자 :

또는 판사 완성 된 스레드 A 후 위의 예제의 경우, 현재 스레드 ID 있지 않은 경우, 키 순간이 만료되었습니다. B 스레드가 잠긴 후 A는 여전히 위의 경우에서 나타났다 수행되었다.

우리는 사용 루아 스크립트를 달성하기 위해, 버클 1 델을 교체해야합니다.

String luaScript = "if redis.call('get', KEYS[1]) == ARGV[1] 
then return redis.call('del', KEYS[1]) else return 0 end";

redisClient.eval(luaScript , Collections.singletonList(key), Collections.singletonList(threadId));

작은 파트너는 다음 먼저, 아직 실행, 스레드 B가 아 규칙을 준수하지 않는 잠금을 획득하기 위해 실행되는 만료 스레드 말해야한다. 여기에서 우리는이 문제를 해결해야합니다.

우리는 JR 가드 르브론 제임스 같은 스레드 칼 가드 (몇 년 전 일)을 설정할 수 있습니다. 임페리얼 가드에, 자바, 스레드의 보호자입니다! 물론, 당신은 스레드의 보호자가 무엇인지 알아야합니다.

이 데몬 스레드는 단 하나 개의 역할

29 초가 경과 한 경우, 스레드 A는 20 초 동안 "생활을 계속"이 시간 데몬 스레드가 잠금에 대한 지침을 만료 실행합니다 수행되지 않았습니다. 데몬 스레드 29 초 실행이 20 초마다 한번 실행하기 시작한다.

 

스레드 A가 실행되면,이 데몬 스레드가 끝날 것입니다.

게시 된 134 개 원래 기사 · 원의 찬양 (91) · 전망 160 000 +

추천

출처blog.csdn.net/weixin_44588495/article/details/104563365