일반적인 오용 사례: 사용자가 결제 버튼을 여러 번 실수로 클릭해 중복 결제를 방지하기 위해, 주문 조작을 할 수 있도록 주문 번호 락(lock)을 사용해 한 스레드만 처리할 수 있도록 합니다.
이 아이디어는 적어도 lock(처리 클래스용 사비 정적 객체)보다는 낫습니다. 왜냐하면 명령 번호를 잠그면 현재 1 명령의 연산만 잠기고, 만약 고정 변수를 잠그면, 즉 모든 명령을 잠그면 모든 명령이 대기열에 들어가게 되는데, 이는 명백히 비합리적입니다.
그렇다면 이 글 처음에 언급한 락(주문 번호) 방법이 원하는 효과를 낼 수 있을까요? 먼저 사용 시나리오를 복원하는 코드를 사용해 보겠습니다.
사용자 정보와 기타 검증을 무시하면, 코드는 대체로 다음과 같습니다:
lock 키워드에 대해서는, MSDN에 Baidu에서 찾을 수 있는 정보가 포함되어 있고, lock(string) 사용은 권장되지 않는 것 같으며, 그 이유는 같습니다. 다음 구절은 MSDN의 자물쇠 줄에 관한 조언에서 발췌한 것입니다:
lock("myLock") 문제는 프로세스에서 같은 문자열을 사용하는 다른 코드가 동일한 락을 공유하기 때문에 발생합니다. 이 문장은 거대한 메커니즘, 즉 "같은 끈"을 숨기고 있습니다.
"같은 줄"이란 무엇인가요? 코드를 확인하세요:
STR1과 STR2가 위의 문자열 중 같은 문자열인가요? 답은 '예'입니다.
다시 보기:
str1과 str2 위도 여전히 같은 줄인가요? 대답은 안 된다야.
좋아요, 주문 결제 문제로 돌아가죠. 우리 코드인 lock(orderNumber)에서, 사용자가 손을 스와이프한 후 실수로 몇 번 더 클릭했을 때, orderNumber가 매번 같은 문자열로 이 동작을 입력하나요? 대답은 안 된다야. 즉,
위 주문을 처리하는 코드는 실제로 잠금장치 역할을 하지 않습니다.
사실, 문자열 비교에는 두 가지 유형이 있으며, 코드를 참고하세요:
위 코드의 첫 번째 줄은 True를, 두 번째 줄은 False를 출력합니다. 제 설명 없이도 MSDN이 말하는 '같은 문자열'이 무슨 뜻인지 이해하실 거라 생각합니다.
최선의 해결책
최적의 잠금 현 해법:
데모 코드:
웹사이트에서는 때때로 전역 변수를 사용할 수 있는데, 이 전역 변수는 여러 사용자가 동시에 접근할 때 비정상적으로 보일 수 있습니다. 이 시점에는 전역 잠금을 설정하지만, 단점은 모든 접근이 차례로 대기한다는 점입니다.
예를 들어, 같은 사용자가 15초 이내에 단 한 번만 댓글을 달 수 있는 경우, 글로벌 락을 사용하면 사용자 수가 급증할 때 댓글 처리 속도가 매우 느려져 사용자 경험에 큰 영향을 미칩니다.
이 시점에서,각 사용자별로 lock(string){...}을 설정할 수 있고, 락의 이름은 다음과 같이 정의할 수 있습니다:메서드 이름 + 사용자 ID이렇게 하면 각 사용자는 독립적인 잠금을 가지며, 댓글 간격을 판단할 때 다른 사용자의 댓글에는 영향을 주지 않습니다.
(끝)
|