Android notify()方法未调用

时间:2017-05-16 09:05:29

标签: android multithreading locking java-threads

我正在尝试使用notify()和wait()。这是我想要的课程。 当我尝试拨打addNewItem()时,我遇到了问题。如果我先调用tryToReadItem()然后调用addNewItem()方法,则不会打印该日志。请注意,我的DemoClass是单身人士。

public class DemoClass {

private static final String TAG = "DemoClass";

private static DemoClass instance;
private Object lock = new Object();
private static Thread executor;
private static Runnable reader;
static MyQueue queue;


private DemoClass() {
    queue = MyQueue.getInstance();
    reader = new Runnable() {

        @Override
        public void run() {
            tryToReadRequest();
        }
    };

}

public static DemoClass getInstance() {
   if (null == instance) {
        instance = new RequestExecutor();
        executor = new Thread(reader);
        executor.run();
    }
    return instance;
}

public boolean addNewItem() {
    synchronized (lock) {
        lock.notify();  // executor will be run
        Log.i(TAG, "executor run...");
    }
    return true;
}

public void tryToReadItem() {

    try {
        while (true) {
            synchronized (lock) {
                if (queue.checkTopValue() == null) {
                    Log.v(TAG, "queue is empty");
                    lock.wait();
                } else {
                    //TODO other code...
                }

            }
        }
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
}

以下是该类的用法:

DemoClass executor = DemoClass.getInstance();
boolean bool = executor.addNewItem();

我错过了什么吗?

编辑:我刚刚更改了我的代码。现在tryToReadRequest()在队列不为空时连续执行。但我的问题是行lock.notify();没有执行。

1 个答案:

答案 0 :(得分:0)

此代码存在许多问题

首先

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<p>Scroll the following container by yourself:</p>
<div class="move">
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit!</p>
</div>

取决于official documentation

  

注意:始终在测试条件的循环内调用wait   等待。不要以为中断是为了   你正在等待的特殊情况,或条件是什么   仍然如此。

您的 if (queue.checkTopValue() == null) { Log.v(TAG, "queue is empty"); lock.wait(); } DemoClass。但不是线程安全 Singleton

因为多个线程可以在相同时间

传递null ==实例条件
Singleton

正确的方法是在synchronized块中使用volatile实例进行额外检查。

所以将volatile添加到实例

   if (null == instance) {
        instance = new RequestExecutor();
        executor = new Thread(reader);
        executor.run();
    }

并将getInstance()方法重写为此类

private static volatile DemoClass instance;

请注意,您只能在同步块内部进行检查,但这会使getInstance方法太慢。