同步线程IllegalStateException

时间:2014-02-19 09:41:03

标签: multithreading blackberry java-me

我已经搜索过并且没有一个主题似乎真的有帮助,我的问题是我在PopupScreen上启动一个线程,等待它完成,然后用适当的通知关闭PopupScreen,这是我的代码

LoginThread lt  = new LoginThread(str1, str2);
lt.start();

synchronized(lt){
    try{
        lt.wait();
    }catch(InterruptedException ie){
        ie.printStackTrace();
    }
    //Everything works fine until here i add
    close();
   //Or
   this.close();

}

private class LoginThread extends Thread{
    public LoginThread(String str1, String str2){

    }

    public void run(){
        synchronized(this){
            notify();
        }
    }
}

有什么建议我可以关闭这个popuscreen吗?

3 个答案:

答案 0 :(得分:3)

响应者应该知道这是一个BlackBerry Java问题,并且有关此处理的BlackBerry Java含义可能在提供的代码中不明显。

从BlackBerry Java的角度来看,显示PopupScreen的原因有很多,其中一个原因是在进行某些后台处理时锁定用户。但是,使用 thread .wait永远不会实现此锁定。 BlackBerry Ui处理使用事件驱动模型,因为我理解它有点像Swing(我不是Swing专家)。这样做的结果是,如果您尝试编写等待代码并且您试图阻止用户继续运行,那么您必须等待事件线程,它会完全阻止用户输入。如果您尝试执行此操作,请使用BlackBerry OS barfs(模拟器除外,因为某些原因它有时会让您这样做)。

有关详情,请参阅此处:

What-is-the-Event-Thread

在这种情况下,一旦长时间运行处理完成,用户希望关闭弹出屏幕。我建议使用像Observer模式这样的模式,换句话说,让线程在完成时回调Observer(PopupScreen)。然后观察者(屏幕)可以自行关闭。

同时,显示的屏幕(Observer)可以忽略通常会关闭它的事件,例如'Esc'键。此屏幕将显示对用户有用的内容,例如“请稍候”。

但需要注意的是,回调将在后台线程中进行,但如果要进行Ui处理,则必须在事件线程上进行关闭。交换到事件线程上下文通常使用如下代码完成:

UiApplication.getUiApplication().invokeLater(new Runnable() {
  public void run() {
    // put code in here
  }
});

这一切都说,我再次建议原始海报搜索,因为我认为有很多这样的样本。在我见过的所有样本中,没有人使用过等待,所以我不太清楚为什么OP试图在第一时间使用等待。如果在样本中看到了这一点,请指出(在评论中),以便我可以尝试修复它。

答案 1 :(得分:0)

在关闭自己之前,您可能必须释放所有锁。将关闭移出同步范围。

另外你应该将start()放在synchronized块中,否则线程可能会在你到达wait()之前通知()。

答案 2 :(得分:-1)

从哪里开始。代码是一团糟,我不会锁定'线程'因为它只是令人困惑。除此之外,你的等待是不可靠的,因为虚假的通知是可能的;所以你可以因为没有特别的原因而被唤醒。

这意味着您需要在循环中执行此操作,但在您的情况下,您没有等待的条件。

我会忘记使用synchronized。在这种情况下,我会看一下你初始化为一个的CountDownLatch。登录线程将进行倒计时,主线程将执行await并阻塞,直到登录线程调用倒计时。这样您就不需要处理自定义同步了。