Java 暂停/恢复线程
我现在有一个tread,当你按下GUI上的一个按钮时开始,这个线程基本上开始下载文件,但我想实现你可以停止tread,这在Java 暂停/恢复线程,java,multithreading,Java,Multithreading,我现在有一个tread,当你按下GUI上的一个按钮时开始,这个线程基本上开始下载文件,但我想实现你可以停止tread,这在t.suspend()中运行良好但它已被弃用,所以我尝试使用t.wait()和t.notify(),问题是每次我尝试暂停时,wait-one都会抛出一个异常“线程中的异常”AWT-EventQueue-0“java.lang.IllegalMonitorStateException” 开始下载按钮: t = new TestTread(); t.start(); 暂停:
t.suspend()中运行良好
但它已被弃用,所以我尝试使用t.wait()代码>和t.notify()代码>,问题是每次我尝试暂停时,wait-one都会抛出一个异常“线程中的异常”AWT-EventQueue-0“java.lang.IllegalMonitorStateException”
开始下载按钮:
t = new TestTread();
t.start();
暂停:
try {
t.wait();
} catch (InterruptedException ex) {
Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
}
继续:
t.notify();
线程类
public class DownloaderThread extends Thread{
@Override
public void run(){
Download();
}
public void Download() {
URL url = new URL(ftpUrl);
URLConnection conn = url.openConnection();
InputStream inputStream = conn.getInputStream();
FileOutputStream outputStream = new FileOutputStream(savePath);
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.close();
inputStream.close();
}
下载工作正常,下载文件时没有任何错误,只是我不能用t.wait停止线程。
我是做错了什么还是以错误的方式实现了等待?您需要更改download()
方法以检查停止或暂停事件,然后停止或暂停线程。必须这样做,因为JVM不知道需要执行哪些步骤才能安全地暂停/停止线程
您可能最终使用了wait
,但不是您使用它的方式wait
使当前运行的线程等待,直到对已调用的对象进行了一些调用notify
在下载方法中有一个循环(读一个块,写一个块)。您应该在循环中添加两个检查
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
if(paused) {
// How do you want to handle pausing? See below for options.
}
if(stopped) {
// delete the file and close the streams.
}
}
如何处理停顿取决于你自己。我可以看到两个选项:将您拥有的内容保存为“.complete”,然后使用标题重新启动下载,或者继续暂停循环(Thread.sleep、Object.wait或其他)。
我会选择第一个选项(范围标题)。这是更多的工作,但也更强大 忘记等待/通知。您没有正确使用它们
设立一个:
volatile boolean pause = false;
现在在您的下载方法中:
while(pause) try {Thread.sleep(1000); } catch (InterruptedException ignore) {}
设置pause true/false控制线程睡眠的时间。中断线程。您应该阅读wait()/notify()
机制的实际内容。这不是一种“暂停”机制(尽管它可以用来实现这一点)。您误解了wait()
。这不会挂起调用它的线程/对象,它会让调用它的线程休眠。它会一直休眠,直到有人对该对象调用notifly()
!我不认为在OP所描述的内容中,打断就足够了。我建议构造一种类型的前置/后置条件集,其中线程只在满足某个条件的情况下执行<代码>字节[]缓冲区=新字节[1024];int字节读取=-1;while((bytesRead=inputStream.read(buffer))!=-1{outputStream.write(buffer,0,bytesRead);}
我需要停止while,但我不知道如何做,因为当我添加另一个语句来检查它是否暂停时,它完全停止下载,我无法恢复它。Updated。该评论应添加到问题中。我已经这样做了。如果实例按照@edharned的建议处理暂停,并使下载线程休眠一秒钟,直到它没有暂停,该怎么办?类似于:while(threadSuspended){try{Thread.sleep(1000);}catch(InterruptedException ex){}}
这样做是一种很好的做法?您打开了到远程服务器的连接,但没有使用它。我不会那样做,因为远程服务器很可能会断开您的连接。关于如何恢复下载的一些示例,请参见。