다음 코드를 실행하려고합니다.
내 생성자에서 원자 부울을 초기화합니다.
Atomic Boolean isChannelActive = new AtomicBoolean(false);
내 쓰기 방법 에서이 부울을 확인하고 기다립니다.
public ChannelFuture write(ByteBuf msgBuf) {
if (!isChannelActive.get()) {
try {
wait();
} catch (InterruptedException ex) {
logger.Error("Waiting interrupted", ex);
}
}
그러나 문제는이 원자 부울이 프로그램이 켜져있을 때 다른 스레드에서 설정할 수 있다는 것입니다.
if (!isChannelActive.get()) {
try{ --- Right on here and program made a context switch at this time.
wait()
따라서이 시나리오에서 내 원자 부울은 true이고 notifyAll () 이벤트를 놓치고 컨텍스트 전환으로 인해 영원히 기다릴 것입니다.
이 문제를 어떻게 방지 할 수 있습니까?
동기화 된 블록이 옵션 일 수 있다는 것을 알고 있지만이 경우에 더 우아한 옵션을 찾고 있습니다.
다른 수준의 동기화 메커니즘을 혼합해서는 안됩니다.
wait/notify
-더 이상 사용할 필요가없는 구식 시스템입니다. 로 할 수있는 모든 wait/notify
작업은 synchronized
또는 Lock
s 로 수행 할 수 있습니다 .
synchronized
-이를 통해 독점 액세스가 필요한 섹션이 서로 간섭하지 않도록 코드를 동기화 할 수 있습니다.
Lock
s-일반적으로 원하는 거의 모든 액세스 제어를 처리 할 수있는 다양한 유형의 잠금이 있습니다.
Blocking...
-이것은보다 현대적인 접근 방식입니다. 코드에 동기화를 두는 대신 데이터 구조를 사용하여 안전한 액세스를 보장합니다.
같은 기능의 추가 설정이 있습니다 Phaser
및 Semaphore
일반적인 메커니즘의 일부를 달성하는 데 사용할 수 있습니다.
당신은 사용 attemptin하는 atomics
과 wait/notify
동시에. 이것은 어려움 없이는 작동하지 않습니다.
아마도 Lock
.
Lock channelActive = new ReentrantLock();
public void test() {
channelActive.lock();
try {
// Do your exclusive stuff here.
} finally {
channelActive.unlock();
}
}
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다