대기() 호출 시 잘못된 MonitorStateException
나는 내 프로그램을 위해 자바에서 멀티스레딩을 사용하고 있다.스레드를 성공적으로 실행했지만 사용할 때는Thread.wait()
, 그것은 던지고 있다.java.lang.IllegalMonitorStateException
어떻게 하면 실이 통지될 때까지 기다리게 할 수 있을까?
넌 지금 이 자리에 있어야 해synchronized
을 위해 봉쇄하다.Object.wait()
일하기 위해
또한, 나는 오래된 학교 실링 패키지 대신 동시성 패키지를 보는 것을 추천한다.그들은 더 안전하고 함께 일하기 더 쉽다.
편집
난 네가 의도한 거라고 생각했어.Object.wait()
예외는 객체를 잠그지 않고 접근하려고 할 때 발생한다.
wait
에 정의되어 있음Object
, 그리고 그것은 아니다.Thread
모니터 켜짐Thread
좀 예측이 불가능해
모든 Java 개체에는 모니터가 있지만, 일반적으로 전용 잠금 장치를 사용하는 것이 더 좋다.
private final Object lock = new Object();
다음과 같은 명명된 클래스를 사용하면 적은 메모리 비용(프로세스당 약 2K)으로 진단 내용을 조금 더 쉽게 읽을 수 있다.
private static final class Lock { }
private final Object lock = new Lock();
위하여wait
또는notify
/notifyAll
물체, 당신은 자물쇠로 자물쇠를 채워야 한다.synchronized
명세서또한, 당신은 a가 필요할 것이다.while
웨이크업 상태를 확인하기 위해 루프(왜 그런지 설명하기 위해 나사산에서 좋은 텍스트를 찾는다).
synchronized (lock) {
while (!isWakeupNeeded()) {
lock.wait();
}
}
알림 방법:
synchronized (lock) {
makeWakeupNeeded();
lock.notifyAll();
}
자바어와 자바어 모두를 이해하는 것은 가치가 있다.java.util.concurrent.locks
자물쇠(그리고)java.util.concurrent.atomic
멀티스레딩에 들어갈 때.그러나 사용java.util.concurrent
가능한 경우 언제든지 데이터 구조
이 실이 2년 가까이 된 건 알지만, 나도 같은 이슈로 이번 Q/A 세션에 왔기 때문에 아직도 닫아야 해.
불법 모니터링의 정의를 읽어 보십시오.몇 번이고 예외...
불법 모니터스레드가 지정된 모니터를 소유하지 않고 객체의 모니터에서 대기하거나 객체의 모니터에서 대기 중인 다른 스레드를 통지하려는 경우 예외를 발생시킨다.
이 줄은 반복해서 "불법 모니터"라고 말한다.예외는 두 가지 상황 중 하나가 발생할 때 발생한다....
1> 지정된 모니터를 소유하지 않고 객체의 모니터에서 대기한다.
2>> 지정된 모니터를 소유하지 않고 객체의 모니터에서 대기 중인 다른 스레드에 통지한다.
몇몇은 답을 알고 있을지도 몰라...모두 그렇지 않은 경우, 그럼 두 개의 문구를 확인하십시오.
동기화된(객체)
object.waitu
두 개체가 동일한 경우...불법 모니터링 없음예외는 올 수 있다.
이제 다시 불법 모니터링을 읽어 보십시오.예외 정의, 그리고 당신은 그것을 다시 잊지 않을 것이다...
당신의 코멘트를 보면 다음과 같은 일을 하고 있는 것처럼 들린다.
Thread thread = new Thread(new Runnable(){
public void run() { // do stuff }});
thread.start();
...
thread.wait();
세 가지 문제가 있다.
다른 사람들이 말했듯이,
obj.wait()
현재 스레드가 에 대한 원시 잠금/음소거 상태를 유지하는 경우에만 호출할 수 있음obj
현재 있는 를 받게 현재 스레드가 잠금을 고정하지 않으면 현재 보고 있는 예외를 받게 된다.그
thread.wait()
전화는 당신이 기대하는 것처럼 보이는 것을 하지 않는다.구체적으로 말하자면thread.wait()
지정된 스레드를 기다리게 하지 않는다.오히려 다른 스레드가 호출될 때까지 현재 스레드가 대기하도록 함thread.notify()
또는thread.notifyAll()
.A를 강제할 안전한 방법은 실제로 없다.
Thread
인스턴스. ( 것은 더 이상 원하 지(지下之)이다. (Java가 이와 가장 가까운 것은 사용되지 않는 인스턴스임.Thread.suspend()
방법, 그러나 그 방법은 자바독에서 설명한 바와 같이 본질적으로 안전하지 않다.)하려면 시스하하면 된다.
Thread
잠시 멈추면 가장 좋은 방법은CountdownLatch
실례를 받고 실권을 행사하다.await()
빗장을 걸어 잠그는 거야그러면 메인 스레드가 전화를 걸 것이다.countDown()
멈춤쇠가 계속되도록 걸쇠에 고정하십시오.이전 점들과 직교하며, a를 사용한다.
Thread
자물쇠/음소거 같은 물체는 문제를 일으킬 수 있다.예를 들어, 자바독은Thread::join
다음과 같이 말한다.의 루프를 한다.
this.wait
에 대한 조건부 전화.this.isAlive
. 실이 끝나기 때문에this.notifyAll
메서드가 호출된다.응용 프로그램은 사용하지 않는 것이 좋다.wait
notify
또는notifyAll
에 관하여Thread
예시
네가 코드를 올리지 않았기 때문에, 우리는 어둠 속에서 일하고 있어.예외에 대한 자세한 내용은?
스레드 내부에서 스레드.wait()로 전화를 거는 겁니까, 아니면 밖에서 거는 겁니까?
내가 이렇게 묻는 이유는 불법 모니터링 상태예외를 위한 자바도크에 따르면 다음과 같다.
스레드가 지정된 모니터를 소유하지 않고 객체의 모니터에서 대기하거나 객체의 모니터에서 대기 중인 다른 스레드를 알리기 위해 던져짐.
이 대답을 명확히 하기 위해, 스레드에서 대기하기 위한 이 호출은 동기화된 블록 내에서 호출되었음에도 불구하고 FailedMonitorStateException을 발생시킨다.
private static final class Lock { }
private final Object lock = new Lock();
@Test
public void testRun() {
ThreadWorker worker = new ThreadWorker();
System.out.println ("Starting worker");
worker.start();
System.out.println ("Worker started - telling it to wait");
try {
synchronized (lock) {
worker.wait();
}
} catch (InterruptedException e1) {
String msg = "InterruptedException: [" + e1.getLocalizedMessage() + "]";
System.out.println (msg);
e1.printStackTrace();
System.out.flush();
}
System.out.println ("Worker done waiting, we're now waiting for it by joining");
try {
worker.join();
} catch (InterruptedException ex) { }
}
FralledMonitorStateException을 처리하려면 모든 대기 호출, 알림 및 알림 확인모든 방법은 호출 스레드가 적절한 모니터를 소유할 때만 이루어진다.가장 간단한 해결책은 이러한 통화를 동기화된 블록 안에 넣는 것이다.동기화된 문에서 호출해야 하는 동기화 개체는 모니터를 획득해야 하는 개체다.
여기 모니터의 개념을 이해하기 위한 간단한 예가 있다.
public class SimpleMonitorState {
public static void main(String args[]) throws InterruptedException {
SimpleMonitorState t = new SimpleMonitorState();
SimpleRunnable m = new SimpleRunnable(t);
Thread t1 = new Thread(m);
t1.start();
t.call();
}
public void call() throws InterruptedException {
synchronized (this) {
wait();
System.out.println("Single by Threads ");
}
}
}
class SimpleRunnable implements Runnable {
SimpleMonitorState t;
SimpleRunnable(SimpleMonitorState t) {
this.t = t;
}
@Override
public void run() {
try {
// Sleep
Thread.sleep(10000);
synchronized (this.t) {
this.t.notify();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
스레드.wait() 호출은 스레드.class 객체에서 동기화하는 코드 내에서 의미가 있다.네가 말한 뜻이 아닌 것 같아.
네가 묻는다
어떻게 하면 알림이 올 때까지 실을 기다리게 할 수 있을까?
현재의 실만 기다리게 할 수 있다.다른 어떤 실도 동의할 경우에만 부드럽게 기다려 달라고 요청할 수 있다.
어떤 조건을 기다리려면 잠금 객체 - 스레드.클래스 객체는 매우 좋지 않은 선택이다 - 싱글톤 AFAIK이기 때문에 스레드 정적 방법을 제외하고 동기화는 위험하다.
동기화와 기다림에 대한 세부사항은 톰 호틴에 의해 이미 설명되어 있다. java.lang.IllegalMonitorStateException
즉, 동기화되지 않은 개체에서 대기하려고 한다는 것을 의미하며, 그렇게 하는 것은 불법이다.
이것이 다른 누군가에게 도움이 될지 아닐지는 확실하지 않지만, 이것은 위의 사용자 "톰 호틴 - 태클린"의 대답에서 나의 문제를 해결하는 중요한 부분이었다.
synchronized (lock) {
makeWakeupNeeded();
lock.notifyAll();
}
단지 "lock"이 synced()에서 인수로 전달되고 "lock".notifyAll()에서도 사용된다는 사실만으로도;
일단 그 두 곳에서 만들었을 때 나는 그것을 작동시켰다.
나는 a를 받았다.IllegalMonitorStateException
다른 사람으로부터 실마리를 깨우려고 애쓰는 동안.class
/ 나사산.인java 8
당신은 새로운 Concurrency API의 기능을 사용할 수 있다.synchronized
기능들
난 이미 물건을 보관하고 있었다.asynchronous
웹셋 트랜잭션WeakHashMap
나의 경우 해결책은 또한 물체를 에 저장하는 것이었다.synchronous
응답들참고:condition.await
(아니오).wait
).
멀티 스레딩을 처리하려면Executors.newCachedThreadPool()
스레드 풀을 생성하십시오.
자바 7.0 이하 버전을 사용하는 분들은 내가 여기서 사용한 코드를 참조하면 된다.
public class WaitTest {
private final Lock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
public void waitHere(long waitTime) {
System.out.println("wait started...");
lock.lock();
try {
condition.await(waitTime, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
lock.unlock();
System.out.println("wait ends here...");
}
public static void main(String[] args) {
//Your Code
new WaitTest().waitHere(10);
//Your Code
}
}
객체에 대해 wait()/notify()를 호출하려면 동기화된 블록 내부에 있어야 한다.그래서 먼저 물체를 잠그고 이 기능을 호출하는 것이 가능할 것이다.
synchronized(obj)
{
obj.wait()
}
자세한 설명은 https://dzone.com/articles/multithreading-java-and-interviewspart-2을 참조하십시오.
참조URL: https://stackoverflow.com/questions/1537116/illegalmonitorstateexception-on-wait-call
'IT이야기' 카테고리의 다른 글
vue 인스턴스의 websocket.onmessage 메서드를 호출하는 방법 (0) | 2022.05.03 |
---|---|
index.html에서 Vue.js 3 인스턴스로 메시지를 보내는 방법 (0) | 2022.05.02 |
C 소켓 Sockaddr 및 Sockaddr_storage의 배후 추론 (0) | 2022.05.02 |
Vue.js 및 Firebase에서 기존 사용자에게 새 데이터를 추가하는 방법 (0) | 2022.05.02 |
내 경로에서 Vue'x getter를 사용할 때 "state.user가 null임" (0) | 2022.05.02 |