gpt4 book ai didi

java.lang.IllegalMonitorStateException : object not locked by thread before wait()?

转载 作者:IT老高 更新时间:2023-10-28 20:45:14 37 4
gpt4 key购买 nike

我正在使用 ProgressDialog。当用户关闭 ProgressDialog 时,我需要停止线程。不幸的是,它给出了一个异常(exception)。

在内部类中:

class UpdateThread extends Thread{

public void run() {
while (true){
count=adapter.getCount();

try {
mHandler.post( new Runnable() {
public void run() {
Log.i(TAG,count+"count");
progressDialog.setMessage(count + "Device found");
}
});
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

创建:

 updateThread=new UpdateThread();

progressDialog= new ProgressDialog(GroupListActivity.this);
synchronized (this) {
updateThread.start();
}

解雇:

   progressDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
try {
synchronized (this) {
updateThread.wait(300);
}

} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i(TAG,"Thread is stopped");
}
});

最佳答案

这是错误的:

synchronized(foo) {
foo.wait();
}

问题是,什么会唤醒这个线程?也就是说,你如何保证另一个线程不会调用foo.notify() 第一个线程调用foo.wait()?这很重要,因为如果 notify 调用首先发生, foo 对象将不会记住它已被通知。如果只有一个 notify(),并且如果它发生在 wait() 之前,那么 wait() 将永远不会返回。

下面是 wait 和 notify 的用法:

private Queue<Product> q = ...;
private Object lock = new Object();

void produceSomething(...) {
Product p = reallyProduceSomething();
synchronized(lock) {
q.add(p);
lock.notify();
}
}

void consumeSomething(...) {
Product p = null;
synchronized(lock) {
while (q.peek() == null) {
lock.wait();
}
p = q.remove();
}
reallyConsume(p);
}

在此示例中要注意的最重要的事情是对条件进行了显式测试(即 q.peek() != null),并且没有人在不锁定锁的情况下更改条件。

如果先调用消费者,那么它会发现队列是空的,它会等待。生产者没有时间可以溜进来,将产品添加到队列中,然后通知锁,直到消费者准备好接收该通知。

另一方面,如果先调用生产者,则保证消费者不会调用wait()。

消费者中的循环之所以重要,有两个原因:其一是,如果有多个消费者线程,那么一个消费者可能会收到通知,但随后另一个消费者会潜入并从中窃取产品。队列。在这种情况下,第一个消费者唯一合理的做法是再次等待下一个产品。循环很重要的另一个原因是 Javadoc 说 Object.wait() 被允许返回,即使对象没有被通知。这就是所谓的“虚假唤醒”,正确的处理方法是返回并再次等待。

另外注意:锁是private,队列是private。这保证没有其他编译单元会干扰此编译单元中的同步。

注意:锁是与队列本身不同的对象。这保证了这个编译单元中的同步不会干扰 Queue 实现所做的任何同步(如果有的话)。


注意:我的示例重新发明了一个轮子来证明一个观点。在实际代码中,您将使用 ArrayBlockingQueue 的 put() 和 take() 方法,它们会为您处理所有等待和通知。

关于java.lang.IllegalMonitorStateException : object not locked by thread before wait()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26590542/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com