if (!hasAccessToken()) { throw new vDiskException("Unable to refresh the Access Token"); } } } } 如果这样改导致死锁,那可能是因为我对 synchronized (UiApplication.getEventLock()) 不了解,并且你这部分的线程设计可能有问题。
// tell progress monitor that progress is interrupted/canceled return; } // tell progress monitor that progress is updated // content } // tell progress monitor that progress is done. }
2 - 有没有要求方法必须是同步执行,即方法确保工作完成以后才返回?
3 - 那个 synchronized (UiApplication.getEventLock())是要确保什么?
在不知道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()) 不了解,并且你这部分的线程设计可能有问题。
并且正确运用了【模态】,
那你不应该用 invokeLater 把它包起来
不是的,前边还有条件判断呢,Application.isEventDispatchThread(),app初始化后就会调用这个push窗口,但是app并没有enterEventDispatcher,所以要先挂起排到队列里
不是的,前边还有条件判断呢,Application.isEventDispatchThread(),app初始化后就会调用这个push窗口,但是app并没有enterEventDispatcher,所以要先挂起排到队列里完全搞不懂你在说什么,能不能叙述得更有条理一些……
谢谢你的回复,看的我云里雾里的,都是专业术语,我用的黑莓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返回之后才能继续后边的操作,不能同步执行。。我对这个多线程不是很明白,所以代码有些莫名其妙,见笑了
条件判断我看到了,如果没有理解错,是为了确保 UiApplication.getUiApplication().pushModalScreen(new LoginScreen());这一句总在EDT内执行new LoginScreen() 必须在EDT内执行可以理解UiApplication.getUiApplication().pushModalScreen() 也必须在EDT内调用吗?
按上下文你这里需要的大概是同步调用,而 invokeLater 是非同步调用
条件判断我看到了,如果没有理解错,是为了确保 UiApplication.getUiApplication().pushModalScreen(new LoginScreen());这一句总在EDT内执行new LoginScreen() 必须在EDT内执行可以理解UiApplication.getUiApplication().pushModalScreen() 也必须在EDT内调用吗?
按上下文你这里需要的大概是同步调用,而 invokeLater 是非同步调用我不行了,你说的太专业了。。这么说吧,所有的invokeLater invokeAndWait之类的都是为了达到目的而做的尝试,没有什么意图,只是为了实现目的。。
原来如此,我还以为你是用的某个框架做Swing程序呢……不过 event queue 的原理是相通的,模态 (modal) 的定义大概也跟Swing里面差不多刚刚去翻了一下黑莓的api,让我始终不太理解的是那个 Application.getEventLock() ,同时也不太理解你在 synchronized(Application.getEventLock()) 里面为什么还要检查 if (Application.isEventDispatchThread())
总之解决了就好……
原来如此,我还以为你是用的某个框架做Swing程序呢……不过 event queue 的原理是相通的,模态 (modal) 的定义大概也跟Swing里面差不多刚刚去翻了一下黑莓的api,让我始终不太理解的是那个 Application.getEventLock() ,同时也不太理解你在 synchronized(Application.getEventLock()) 里面为什么还要检查 if (Application.isEventDispatchThread())
总之解决了就好……还得麻烦问你一个问题,还是同一个软件,这次是分段上传的,首先打开一个进度窗口,进度窗口调用一个新线程去分割大文件,分割成n段之后用for把每一段上传,上传用的是runnable,上传没有问题,但是我如果想中途中断上传的话,进度窗口调用新线程的stop方法去interrupt去终止线程,但是线程中的runnable不会中断,这个应该怎么处理呢?
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.
}