java IllegalMonitorStateException:对象在notify()之前未被线程锁定

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25267571/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 07:44:25  来源:igfitidea点击:

IllegalMonitorStateException: object not locked by thread before notify()

javaandroidmultithreading

提问by user154989

Yes, I have seen previous questions on similar topics, but they don't seem to help me. If there is a duplicate, please point me to the question, thanks

是的,我之前看过有关类似主题的问题,但它们似乎对我没有帮助。如果有重复,请指出问题,谢谢

I have two problems here, the first one is the title problem:

我这里有两个问题,第一个是标题问题:

@Override
protected void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
//Starts up method1 & method2 in a try-catch
    try{
        method1();
        method2();
        new CountDownLatch(1);
        CountDownLatch.await();
    }catch(InterruptedException e){
        // TODO Auto-generated catch
        // block
        e.printStackTrace();
    }
//This Toast should only run after notify() is called
    Toast.makeText(firstClass.this, "This is toasty", Toast.LENGTH_SHORT).show();
}


//Start of method 1, which is currently useless
public void method1() throws InterruptedException{
//Creates new thread
    Thread thread = new Thread(new Runnable(){
        @Override
        public void run(){
            try{
                synchronized(SecondClass.this){
                }
            }catch(Exception e){
                e.printStackTrace();
            }
        }

    });
    thread.start();
}

public void method2(){
    Thread thread2 = new Thread(new Runnable(){
        @Override
        public void run(){

//Sets a button, when the button is clicked, then the code is continued
                final Button bNext = (Button) findViewById(R.id.bIsoAbunSave);
                bNext.setOnClickListener(new OnClickListener(){
                    @Override
                    public void onClick(View arg0){
                        synchronized(SecondClass.this){
                        CountDownLatch.countDown();
                       }
                    }
                });
            }


    });
    thread2.start();
}

From what I understand, please correct me if its false, what wait() does is it halts all running code until an event, such as a click of a button causes notify() to be called.

据我所知,如果它是错误的,请纠正我,wait() 的作用是停止所有正在运行的代码,直到发生事件,例如单击按钮导致调用 notify()。

The second problem is even before I click the button, the Toast shows up. I assumed when I called wait(), all code would waituntil I clicked the button, where notify() would be called and the code would be continued. But what happens instead is that the Toast is seemingly ignoring the wait() and running anyways.

第二个问题甚至在我单击按钮之前,Toast 就会出现。我假设当我调用 wait() 时,所有代码都会等到我单击按钮,然后调用 notify() 并继续执行代码。但是发生的事情是 Toast 似乎忽略了 wait() 并且无论如何都在运行。

If there are any questions, please ask away, thanks.

如有问题请追问,谢谢。

EDIT: The logcat message shows that the crash happens at:

编辑:logcat 消息显示崩溃发生在:

synchronized(SecondClass.this){notify();}

回答by Marco Acierno

Here

这里

synchronized(this){
//Sets a button, when the button is clicked, then the code is continued
            final Button bNext = (Button) findViewById(R.id.bIsoAbunSave);
            bNext.setOnClickListener(new OnClickListener(){
                @Override
                public void onClick(View arg0){
                    notify();
                }
            });
}

You lock the invocation of findViewByIdand the setOnClickListenerbut not the onClick method, so when is invoked notifyis outside any syncronized block.

你锁定的调用findViewByIdsetOnClickListener,但不是的onClick方法,因此被调用时notify超出任何syncronized块。

You should move the lock inside the onClickmethod which is the code-block to block

您应该将锁移动onClick到要阻止的代码块的方法中

//Sets a button, when the button is clicked, then the code is continued
            final Button bNext = (Button) findViewById(R.id.bIsoAbunSave);
            bNext.setOnClickListener(new OnClickListener(){
                @Override
                public void onClick(View arg0){
                    synchronized(TopClass.this){ notify(); }
                }
            });

(remember thisis different in an inner-class)

记住this在内部类中是不同的

Anyway the use of wait/notifyis not recommended, consider using one of the other multithread classes and collections in the JDK.

无论如何wait/notify不推荐使用,请考虑使用 JDK 中的其他多线程类和集合之一。



synchronized(this){
   //These statements *should* make the code wait until I click the button
   wait();
}

Here you syncronizate the Runnablenot the main class.

在这里,您同步了Runnable非主类。