简体   繁体   English

Android java.lang.IllegalMonitorStateException:对象在wait()之前未被线程锁定

[英]Android java.lang.IllegalMonitorStateException: object not locked by thread before wait()

I define a global static object as a synchronization lock. 我将全局静态对象定义为同步锁。

public static Object ConfirmationSynObj = new Object();

The following function is what I wrote, but it throw a IllegalMonitorStateException. 我写的是以下函数,但它抛出了IllegalMonitorStateException。

       synchronized (Config.ConfirmationSynObj) {
            new Thread(new Runnable() {

                @Override
                public void run() {
                    //this is a http request
                    appSignInfo = getAPKSignature(context, pkinfo.packageName);
                    Config.ConfirmationSynObj.notify();
                }
            }).start();
            try {
                Config.ConfirmationSynObj.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            if (appSignInfo == null) {
                return ret;
            }
        }

Does anyone know how to lock an object or a function in order to prevent the concurrency? 有谁知道如何锁定对象或函数以防止并发?

A common replacement for wait / notify is CountDownLatch . wait / notify常见替代是CountDownLatch (From java.util.concurrent as well but working kind of inverse of Semaphore - see answer by Tom) (来自java.util.concurrent以及Semaphore的反向工作 - 请参阅Tom的回答)

You initialize it to the amount of steps required, threads that have finished count down and some other place waits for the countdown to reach 0. 您将其初始化为所需的步骤数,已完成倒计时的线程以及其他某些位置等待倒计时达到0。

void doFoo() {
    final CountDownLatch latch = new CountDownLatch(1);
    new Thread(new Runnable() {

        @Override
        public void run() {
            //this is a http request
            appSignInfo = getAPKSignature(context, pkinfo.packageName);
            latch.countDown();
        }
    }).start();
    try {
        latch.await();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    if (appSignInfo == null) {
        return ret;
    }
}

But the code you wrote there can be simplified to 但是你在那里写的代码可以简化为

void doFoo() {
    return getAPKSignature(context, pkinfo.packageName);
}

You start a second thread to do something and all you do in that time is to wait. 你开始第二个线程做某事,你在那段时间所做的就是等待。 If there is nothing to do while that task is running don't create an extra thread. 如果在该任务运行时无事可做,请不要创建额外的线程。 The result is the same. 结果是一样的。

If you try to do a HTTP request outside of the UI thread because you get that NetworkOnMainThreadExcpeption , you have to do it differently. 如果您尝试在UI线程之外执行HTTP请求,因为您获得了NetworkOnMainThreadExcpeption ,则必须以不同方式执行此操作。 While Android won't detect your code as long time blocking code it still is. 虽然Android不会长时间阻止代码检测到您的代码,但它仍然存在。 Use an AsyncTask for example. 例如,使用AsyncTask。

@Kayaman speaks correctly, as far as I can tell, however if I may humbly suggest: java.util.concurrent can save you lots of time! @Kayaman说的正确,据我所知,但是如果我可能谦卑地建议: java.util.concurrent可以节省你很多时间!

What I'd use there is a semaphore . 我在那里使用的是一个信号量

From the docs: "Each acquire() blocks if necessary until a permit is available, and then takes it.". 从文档:“每个acquire()必要时阻止,直到有许可证,然后接受它。”

But there are other choices too- I strongly recommend using this where possible, as you should avoid lots of pit falls as in your case. 但是还有其他选择 - 我强烈建议在可能的情况下使用它,因为你应该避免像你的情况那样陷阱。

        Semaphore semaphore = new Semaphore(0);
        new Thread(new Runnable() {

            @Override
            public void run() {
                //this is a http request
                appSignInfo = getAPKSignature(context, pkinfo.packageName);
                semaphore.release();
            }
        }).start();
        try {
            semaphore.acquire();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

You might be creating and starting the thread in the synchronized block, but when the thread comes to Config.ConfirmationSynObj.notify(); 您可能正在同步块中创建并启动线程,但是当线程进入Config.ConfirmationSynObj.notify(); you'll notice that there's no synchronization. 你会注意到没有同步。

You'll need to add a synchronized block inside run(). 您需要在run()中添加一个synchronized块。

 new Thread(new Runnable() {

            @Override
            public void run() {

Above thread is not owning lock on ConfirmationSynObj object hence throwing IllegalMonitorStateException 上面的线程没有在ConfirmationSynObj对象上拥有锁,因此抛出了IllegalMonitorStateException

Use one more synchronized block inside run method run方法中使用一个以上的同步块

           @Override
            public void run() {
            synchronized (Config.ConfirmationSynObj) {
                //this is a http request
                appSignInfo = getAPKSignature(context, pkinfo.packageName);
                Config.ConfirmationSynObj.notify();
               }
            }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Android:java.lang.IllegalMonitorStateException:对象在wait()之前未被线程锁定 - Android: java.lang.IllegalMonitorStateException: object not locked by thread before wait() java.lang.IllegalMonitorStateException:对象在wait()之前未被线程锁定 - java.lang.IllegalMonitorStateException: object not locked by thread before wait() java.lang.IllegalMonitorStateException:在等待()之前对象没有被线程锁定? - java.lang.IllegalMonitorStateException: object not locked by thread before wait()? 线程“main”java.lang.IllegalMonitorStateException中的异常 - Exception in thread “main” java.lang.IllegalMonitorStateException 线程“ AWT-EventQueue-0”中的异常java.lang.Object.notify上的java.lang.IllegalMonitorStateException(本机方法) - Exception in thread “AWT-EventQueue-0” java.lang.IllegalMonitorStateException at java.lang.Object.notify(Native Method) IllegalMonitorStateException: 对象在 wait() 之前未被线程锁定,使用同步静态方法 - IllegalMonitorStateException: object not locked by thread before wait(), using synchronized static method 从同步块中调用wait时发生java.lang.IllegalMonitorStateException - java.lang.IllegalMonitorStateException whilst calling wait from synchronized block 超时时发生java.lang.IllegalMonitorStateException - java.lang.IllegalMonitorStateException on timeout java.lang.IllegalMonitorStateException: 当前线程不是锁的所有者 - java.lang.IllegalMonitorStateException: Current thread is not owner of the lock 线程通信:如何发出信号,表明已单击某个键? java.lang.IllegalMonitorStateException - Thread communication: How to signal that a key was clicked? java.lang.IllegalMonitorStateException
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM