Java 线程停止通知程序

Java Thread stop notifier

我这里的任务是使用多线程执行解压缩操作。我用以下结构方式做到了。

// A class for Unzipping files
public class UnzipClass extends Thread(){
    private String zipfile;
    private Thread t;
    public UnzipClass(String zipFile){
       this.zipFile = zipFile;
    }

    public String getZipFile() {
       return zipFile;
    }

    public void setZipFile(String zipFile) {
       this.zipFile = zipFile;
    }

    public void run() {
    try {
        unzipFolder(this.getZipFile());
    } catch (IOException ex) {
        Logger.getLogger(Unzipper.class.getName()).log(Level.SEVERE, null, ex);
    }
}
public void start(String filename){
    if (t == null){
        t = new Thread(this,filename);
        t.start();
    }
}
public unzipFolder(String zipFile) throws ZipException, IOException   
    // Here is the Unzip Method 
 }

}

// Now I am calling this class from another class
public static void main(){
   Thread t1 = new UnzipClass("filename1");  
   t1.start();
    if(!(t1.isAlive())){
      logEvent("Unzip Complete");
    } 

  // Similarly I have Thread t2 with another file name 

 }

以上代码运行完美并解压缩文件,但我遇到以下问题。

  1. 我想使用 implements Runnable ,但我不能使用它,因为我没有找到将变量(文件名)传递给另一个 class 实现 Runnable 并执行它。字面意思:How to implement Runnable instead of extends Thread`

  2. 使用上述方法,如何检测解压缩过程是否已完成。具体如何在文件解压过程完成时停止线程`。

任何类型的提示或解决方案都非常棒。

提前致谢。

import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipException;

public class UnzipClass {
    // Now I am calling this class from another class
    public static void main() {
        Thread t1 = new Thread(new UnzipClassRunner("filename1"));
        t1.start();
        try {
            t1.join();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}

class UnzipClassRunner implements Runnable {
    private String zipfile;


    public UnzipClassRunner(String zipFile) {
        this.zipfile = zipFile;
    }

    public void run() {
        try {
            unzipFolder(zipfile);
        } catch (IOException ex) {
            Logger.getLogger(Unzipper.class.getName()).log(Level.SEVERE, null,
                    ex);
        }
    }

    public void unzipFolder(String zipFile) throws ZipException, IOException {
        //
    }
}

只需将 extends Thread 更改为 implements Runnable

创建新线程时,你会做

Thread t1 = new Thread(new UnzipClass("filename1"));

而不是

Thread t1 = new UnzipClass("filename1");

如果您想同时解压缩几个文件,请尝试使用 ExecutorService。您可以 submit Runnable 任务由线程池执行 - 这样,您将重用已经存在的线程。 检查 Executors and ExecutorService

1.change

public class UnzipClass extends Thread

进入

public class UnzipClass implements Runnable 

并使用

Runnable t1 = new UnzipClass("filename1");

创建线程。

2。 在此处使用 while 循环

while((t1.isAlive())){
  logEvent("Unziping...");
} 

logEvent("Unzip Complete");

但是在 UnzipClass 中使用像 boolean isComplete 这样的标志会更有效。喜欢

在classUnzipClass中添加

private boolean complete=false;

然后,

public void run() {
try {
    unzipFolder(this.getZipFile());
    complete=true;
} catch (IOException ex) {
    Logger.getLogger(Unzipper.class.getName()).log(Level.SEVERE, null, ex);
}
}

//simple getter.
public boolean isComplete()
{
    return this.complete;
}

主要...

while(!t1.isComplete()){
  logEvent("Unziping...");
} 

logEvent("Unzip Complete");

请检查此解决方案。

它使用 Java 8 个功能,但可以轻松升级以与 Java 5 / 6 / 7(和外部库,如 Apache Commons 或 Guava)一起使用。

/**
 * File unzipping service
 */
public class Unzipper {

    /**
     * Default number of threads
     */
    private static byte DEFAULT_THREADS_COUNT = 5;

    /**
     * Completion handler
     */
    private Consumer onComplete;

    /**
     * Unzipping tasks
     */
    private Collection<File> unzippingTasks = new LinkedList<>();

    /**
     * Add task for unzipping file
     *
     * @param file Path to file to be unzipped
     * @return upgraded <code>this</code> instance
     */ 
    public Unzipper unzip(String file) {

        //check validity of 'file' string: non-null and non-empty
        //check that file pointed by 'file' exists

        unzippingTasks.add(new File(file));
        return this;
    }

    /**
     * Add unzipping completion handler
     * 
     * @param onComplete Unzipping completion handler
     * @return upgraded <code>this</code> instance
     */
    public Unzipper onComplete(Consumer onComplete) {

        //check validity of 'onComplete' object: non-null
        this.onComplete = onComplete;
        return this;
    }

    /**
     * Run files unzipping (with default number of threads)
     */
    public void run() {
        run(DEFAULT_THREADS_COUNT);
    }

    /**
     * Run files unzipping
     *
     * @param threads Number of parallel threads
     */
    public void run(byte threads) {

        //check validity of 'threads' argument: non-negative and non-zero

        //check that we have at least one 'unzipping' task
        if(unzippingTasks.isEmpty()) {

            //output to log that unzipping tasks list is empty
            return;
        }

        CountDownLatch latch = new CountDownLatch(threads);
        Executor executor = Executors.newFixedThreadPool(threads + 1); //we are not blocking in 'run' method, so we should create extra thread to wait for all tasks completion

        for(File file: unzippingTasks) {

            executor.execute(() -> {
                //unzip file
                latch.release();
            });
        }

        executor.execute(() -> {

            latch.await(); //wait for all unzipping tasks completion
            if(onComplete) //you can use 'optional' here instead
                onComplete.accept(null);
        });

        executor.shutdown();
    }
}

....

//Usage example
new Unzipper()
    .unzip("<path-to-some-file>")
    .unzip("<path-to-another-file>")
    .unzip("<path-to-some-another-file>")
    .onComplete(() -> {
        //make you log output
    })
    .run();