【问题标题】:Synchronized Thread IllegalStateException同步线程 IllegalStateException
【发布时间】:2014-02-19 09:41:02
【问题描述】:

我已经搜索过,但似乎没有一个主题真的有帮助,我的问题是我在 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();
        }
    }
}

有什么建议可以关闭这个弹出屏幕吗?

【问题讨论】:

  • @downvoter - 我认为没有理由不赞成这个问题。请解释一下自己..

标签: multithreading blackberry java-me


【解决方案1】:

响应者应该知道这是一个 BlackBerry Java 问题,并且 BlackBerry Java 对这种处理的影响可能在所提供的代码中并不明显。

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

有关更多信息,请参见此处:

What-is-the-Event-Thread

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

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

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

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

说了这么多,我建议重新搜索原始海报,因为我认为周围有很多这样的样本。在我见过的所有样本中,都没有人使用过等待,所以我不太明白为什么 OP 一开始就尝试使用等待。如果这已在示例中看到,请指出它(在评论中),以便我可以尝试修复它。

【讨论】:

  • 我没有在任何示例中看到它,但我想不出另一个等待线程完成,但您的建议帮助我将 close() 放入您提供的运行方法中,并且成功了,谢谢
  • “同步线程非法状态异常”我的问题是关于“关闭”它而不是它是如何工作的,我可以用 if(c == Characters.ESCAPE)close() 关闭它,这是它似乎工作的唯一情况
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

    从哪里开始。代码一团糟,我不会锁定“线程”,因为它只是令人困惑。除此之外,您的等待是不可靠的,因为可能会出现虚假通知;这样你就可以无缘无故被吵醒。

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

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

    【讨论】:

      猜你喜欢
      • 2019-03-25
      • 2014-04-30
      • 1970-01-01
      • 1970-01-01
      • 2018-12-23
      • 2016-01-20
      • 1970-01-01
      相关资源
      最近更新 更多