等待对象初始化

Meg*_*ron 6 java wait

我有一个在一个单独的线程中初始化的对象.在填充本地数据库时,初始化可能需要几秒钟.

SpecialAnalysis currentAnalysis = new SpecialAnalysis(params_here);
Run Code Online (Sandbox Code Playgroud)

我正在尝试实现一个"取消"按钮,它将对象的isCancelled布尔值设置为true.实现这个的正确Java方法是什么?

while (currentAnalysis == null) {
}
currentAnalysis.cancel();
Run Code Online (Sandbox Code Playgroud)

该方法冻结了程序,因为它似乎进入了计算效率低下的循环.这是我可以使用的情况Object.wait()吗?

我目前的糟糕/半成功的解决方案是:

while (currentAnalysis == null) {
    Thread.sleep(500);
}
currentAnalysis.cancel();
Run Code Online (Sandbox Code Playgroud)

谢谢!

wil*_*roz 8

首先,是Object.wait()Object.notify()/ Object.notifyAll()是你需要的.你是否直接使用它们是另一回事.由于易于编程,wait/notify因此通常建议使用Java 1.5中添加并发工具(参见下面的第二种方法).


传统wait/notify方法:

初始化:

    synchronized (lockObject) {
        SpecialAnalysis currentAnalysis = new SpecialAnalysis(params_here);
        lockObject.notifyAll();
    }
Run Code Online (Sandbox Code Playgroud)

在'取消'主题中:

    synchronized (lockObject) {
        while (currentAnalysis == null) {
            try { lockObject.wait(); }
            catch Exception(e) { } // FIXME: ignores exception
        }
    }
    currentAnalysis.cancel();
Run Code Online (Sandbox Code Playgroud)

当然,这些可以是同步方法而不是块.您的选择lockObject将取决于您需要多少"取消"线程等.理论上它可以是任何东西,即Object lockObject = new Object();只要您小心正确的线程可以访问它.

请注意,wait()由于可能存在来自底层OS 的虚假唤醒,因此将调用置于此处的while循环中非常重要.


一个更简单的方法是使用a CountDownLatch,从wait()&的螺母和螺栓中饶恕你notify():

(我在这里做了几个假设,以便提出一个可能更清晰的方法).

    class AnalysisInitialiser extends Thread {

        private CountDownLatch cancelLatch = new CountDownLatch(1);
        private SpecialAnalysis analysis = null;

        @Override
        public void run() {
            analysis = new SpecialAnalysis(params);
            cancelLatch.countDown();
        }

        public SpecialAnalysis getAnalysis() {
            cancelLatch.await();
            return analysis;
        }
    }
Run Code Online (Sandbox Code Playgroud)

然后在需要发送取消信号的线程中:(显然你需要以AnalysisInitialiser某种方式获取对象)

    analysisInit.getAnalysis.cancel();
Run Code Online (Sandbox Code Playgroud)

没有并发原语样板,耶!