暂停/恢复线程

时间:2015-11-26 13:59:37

标签: java multithreading

我现在有一个在你按下GUI上的按钮时启动,这个线程基本上开始下载文件,但我想实现你可以停止踏板,这对t.suspend();工作得很好但是它不推荐使用,所以我尝试使用t.wait();t.notify();,问题是wait等抛出异常“线程中的异常”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停止线程。 我做错了什么还是我以错误的方式实施等待?

2 个答案:

答案 0 :(得分:3)

您需要更改download()方法以检查停止或暂停事件,然后停止或暂停线程。必须采用这种方式,因为JVM不知道需要采取哪些步骤才能安全地暂停/停止线程。

您最终可能会使用wait,但不会使用它。 wait导致当前正在运行的线程等待,直到您调用notify的对象上的某些调用wait为止。

在下载方法中,您有一个循环(读取一个块,写一个块)。你应该在循环中添加两个检查。

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. 
      }
} 

你如何处理暂停取决于你。我可以看到两个选项:将您拥有的内容保存为“.incomplete”,然后使用Range标头重新启动下载,或者继续循环暂停(Thread.sleep,Object.wait或其他)。 我会选择第一个选项(Range Header)。这是更多的工作,但也更健壮。

答案 1 :(得分:0)

忘记等待/通知。你没有正确使用它们。

设置:

volatile boolean pause = false;

现在在您的下载方法中:

while(pause) try {Thread.sleep(1000); } catch (InterruptedException ignore) {}

设置暂停true / false控制线程休眠的时间。