解决方案 »

  1.   

    一定要用 1.3 ?是 Swing 程序吗?1.3 的模态 (modal) 是怎样工作的,不太清楚……另外:1 - 这个方法是在哪个线程调用的? 有没有可能是 EDT?
    2 - 有没有要求方法必须是同步执行,即方法确保工作完成以后才返回?
    3 - 那个 synchronized (UiApplication.getEventLock())是要确保什么?
      

  2.   


    在不知道1楼所说的这些东西的情况下,
    我猜你的问题情况是:调用来自非EDT线程,invokeLater之后直接检查导致失败,
    能给你的最好的建议就是看看 UiApplication.getApplication() 有没有 invokeAndWait 方法,我猜UiApplication.getApplication()是个单例,并且对 SwingUtilities/EventQueue 的一些方法作了封装
    原代码第 14 行:public void refreshAccessToken(boolean force) throws vDiskException
        {
            synchronized (UiApplication.getEventLock())
            {
                if (force) // || !isAccessTokenValid()) {
                {
                    setAccessToken(null);
                    if (Application.isEventDispatchThread())
                    {
                        UiApplication.getUiApplication().pushModalScreen(new LoginScreen());
                    } else {
                        UiApplication.getApplication().invokeAndWait(new Runnable() {
                            public void run() {
                                UiApplication.getUiApplication().pushModalScreen(new LoginScreen());
                            }
                        });
                        // 可能会有 checked exception 需要处理
                    }
     
                    if (!hasAccessToken()) {
                        throw new vDiskException("Unable to refresh the Access Token");
                    }
                }
            }
        }
    如果这样改导致死锁,那可能是因为我对 synchronized (UiApplication.getEventLock()) 不了解,并且你这部分的线程设计可能有问题。
      

  3.   

    如果 UiApplication.getUiApplication().pushModalScreen() 可以在任何线程调用,
    并且正确运用了【模态】,
    那你不应该用 invokeLater 把它包起来
      

  4.   


    不是的,前边还有条件判断呢,Application.isEventDispatchThread(),app初始化后就会调用这个push窗口,但是app并没有enterEventDispatcher,所以要先挂起排到队列里
      

  5.   


    不是的,前边还有条件判断呢,Application.isEventDispatchThread(),app初始化后就会调用这个push窗口,但是app并没有enterEventDispatcher,所以要先挂起排到队列里完全搞不懂你在说什么,能不能叙述得更有条理一些……
      

  6.   


    谢谢你的回复,看的我云里雾里的,都是专业术语,我用的黑莓jdk,最高只支持到1.3,没办法不过问题我已经解决了,在调用refreshAccessToken()的函数里加锁,然后在refreshAccessToken()里解锁,就是在pushModelScreen返回之后,就搞定了synchronized (ACCESS_TOKEN_LOCK) {
    if (!hasAccessToken())
    {
    refreshAccessToken(true);
    try {
    ACCESS_TOKEN_LOCK.wait(vDiskConfig.AUTHORIZE_TIMEDOUT);
    } catch (InterruptedException e) {}
    }
    }我的要求就是必须等LoginScreen返回之后才能继续后边的操作,不能同步执行。。我对这个多线程不是很明白,所以代码有些莫名其妙,见笑了
      

  7.   


    条件判断我看到了,如果没有理解错,是为了确保 UiApplication.getUiApplication().pushModalScreen(new LoginScreen());这一句总在EDT内执行new LoginScreen() 必须在EDT内执行可以理解UiApplication.getUiApplication().pushModalScreen() 也必须在EDT内调用吗?
    按上下文你这里需要的大概是同步调用,而 invokeLater 是非同步调用
      

  8.   


    条件判断我看到了,如果没有理解错,是为了确保 UiApplication.getUiApplication().pushModalScreen(new LoginScreen());这一句总在EDT内执行new LoginScreen() 必须在EDT内执行可以理解UiApplication.getUiApplication().pushModalScreen() 也必须在EDT内调用吗?
    按上下文你这里需要的大概是同步调用,而 invokeLater 是非同步调用我不行了,你说的太专业了。。这么说吧,所有的invokeLater invokeAndWait之类的都是为了达到目的而做的尝试,没有什么意图,只是为了实现目的。。
      

  9.   


    原来如此,我还以为你是用的某个框架做Swing程序呢……不过 event queue 的原理是相通的,模态 (modal) 的定义大概也跟Swing里面差不多刚刚去翻了一下黑莓的api,让我始终不太理解的是那个 Application.getEventLock() ,同时也不太理解你在 synchronized(Application.getEventLock()) 里面为什么还要检查 if (Application.isEventDispatchThread()) 
    总之解决了就好……
      

  10.   


    原来如此,我还以为你是用的某个框架做Swing程序呢……不过 event queue 的原理是相通的,模态 (modal) 的定义大概也跟Swing里面差不多刚刚去翻了一下黑莓的api,让我始终不太理解的是那个 Application.getEventLock() ,同时也不太理解你在 synchronized(Application.getEventLock()) 里面为什么还要检查 if (Application.isEventDispatchThread()) 
    总之解决了就好……还得麻烦问你一个问题,还是同一个软件,这次是分段上传的,首先打开一个进度窗口,进度窗口调用一个新线程去分割大文件,分割成n段之后用for把每一段上传,上传用的是runnable,上传没有问题,但是我如果想中途中断上传的话,进度窗口调用新线程的stop方法去interrupt去终止线程,但是线程中的runnable不会中断,这个应该怎么处理呢?
      

  11.   


    interrupt 我没有用过,我一般自设一个flag,不过我在别的地方看到过,
    貌似 interrupt 只是一种提醒线程结束的方式,而不是强制线程结束,
    需要你自己在 Runnable 内检查 Thread.interrupted() ,比如你用了for循环,大概是这样:  @Override
      public void run() {
        
        for (<initial>; <condition>; <change>) {
          
          if (Thread.interrupted()) {
            
            // tell progress monitor that progress is interrupted/canceled
            return;
          }      // tell progress monitor that progress is updated
          // content
        }    // tell progress monitor that progress is done.
      }