不幸的是,我对如何正确设置线程非常不了解。我知道SO.SE和其他网站上都有大量的信息,但我似乎无法将我正确阅读的内容与我正在做的事情联系起来。
我的问题是我有一个方法,它接受两个参数,其中一个被另一个分开。商(结果)用于填充可视进度条。当商得到1,(readBytes/contentLength == 1)
时,我想要一些线程(我猜)在从布局中删除进度条之前等待给定时间。我知道将值设置到进度条所需的所有代码以及如何从视图中删除它,我的问题是如何让它等待,比如说,在触发操作之前2000毫秒移除组件?
这可能是基本的线程知识,但我遇到了很多问题。
到目前为止,我已尝试过这两种方法:
@Override
public void updateProgress(long readBytes, long contentLength) {
this.contentLength = contentLength;
if(readBytes != 0 && contentLength != 0 && fileListItem != null) {
fileListItem.getProgressIndicator().setValue(readBytes/contentLength);
synchronized (this) {
while(readBytes/contentLength != 1) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
};
fileListItem.removeProgressIndicator();
}
}
}
if(!itemIsAdded) {
checkFileCompatibility(contentLength);
}
}
和
@Override
public void updateProgress(long readBytes, long contentLength) {
this.contentLength = contentLength;
if(readBytes != 0 && contentLength != 0 && fileListItem != null) {
if(readBytes/contentLength == 1) {
Thread t = new Thread();
t.start();
try {
t.wait(2000);
fileListItem.removeProgressIndicator();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t.interrupt();
} else {
fileListItem.getProgressIndicator().setValue(readBytes/contentLength);
}
}
if(!itemIsAdded) {
checkFileCompatibility(contentLength);
}
}
没有成功。在第一个例子中,主线程似乎是等待的,没有任何反应。在第二个例子中,我在t.wait(2000);
上得到了一个例外。我不知道该怎么做..
编辑:根据波希米亚人的意见,我开始工作了。
@Override
public void updateProgress(final long readBytes, final long contentLength) {
this.contentLength = contentLength;
if(readBytes != 0 && contentLength != 0 && fileListItem != null) {
if(!threadIsRunning) {
new Thread(new Runnable() {
@Override
public void run() {
threadIsRunning = true;
while(!fileIsAdded) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
LOGGER.error(e.getMessage());
break;
}
}
fileListItem.removeProgressIndicator();
threadIsRunning = false;
}
}).start();
}
fileListItem.getProgressIndicator().setValue(readBytes/contentLength);
if(readBytes == contentLength)
fileIsAdded = true;
}
if(!itemIsAdded) {
checkFileCompatibility(contentLength);
}
}
它仍然需要整理,但基础知识现在正在运作!
答案 0 :(得分:2)
很有可能SwingWorker是适合您任务的正确工具。 Javadoc中有完整的代码示例。请注意方法setProgress
- 这是更新进度条的理想选择。
如果您只需要一个固定的2秒延迟来清除进度条,那么您想要使用Swing Timer。它甚至不涉及多线程,你只需编写一个将在指定的延迟后执行的回调处理程序。
答案 1 :(得分:1)
我认为你真正需要的是
Thread.sleep(2000);
而不是wait
。虽然wait
可以用于休眠,但它的主要功能是用于线程间信令,并且需要锁定正在等待的对象,这是你没有获得的,因此是例外。
修改:进一步检查后,我发现您没有正确处理。您只是创建一个没有关联run
方法的线程:
Thread t = new Thread();
t.start();
因此你的线程没有执行任何操作。
我建议您阅读有关如何正确设置线程的Java线程教程:http://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html
答案 2 :(得分:1)
我不会让主线程等待。这是不好的做法,因为它不可扩展,使你的GUI紧张。
相反,我会将超时值和几个callbacks传递给工作线程,以便在超出其超时/完成其工作时执行。这样主线程可以自由地回去做任何想做的事情。
仅出于说明目的,您的“完成”回调可能如下所示:
new Runnable() {
public void run() {
// code that hides the progress bar
}
}
您的“超时”回调可能如下所示:
new Runnable() {
public void run() {
// code that displays an error message
}
}
顺便说一句,要获得一个线程来做某事,你也可以传递一个Runnable:
new Thread(new Runnable() {
public void run() {
// code that runs when your thread starts
}
}).start();