Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中线程的终止条件_Java_Multithreading_Concurrency - Fatal编程技术网

Java中线程的终止条件

Java中线程的终止条件,java,multithreading,concurrency,Java,Multithreading,Concurrency,我已经编写了一个多线程Java应用程序,它从一个目录中读取大量.jar文件。这个应用程序产生多个线程,每个线程读取一堆jar文件。识别此应用程序的停止条件时遇到问题。如何确定所有文件都已读取 下面是一个snippet函数,该函数通过run()方法为每个线程调用 import java.io.*; import java.util.Enumeration; import java.util.jar.*; import java.util.zip.ZipEntry; import java.

我已经编写了一个多线程Java应用程序,它从一个目录中读取大量.jar文件。这个应用程序产生多个线程,每个线程读取一堆jar文件。识别此应用程序的停止条件时遇到问题。如何确定所有文件都已读取

下面是一个snippet函数,该函数通过run()方法为每个线程调用

    import java.io.*;
import java.util.Enumeration;
import java.util.jar.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipException;
import java.io.FilenameFilter;

public class ArchiveFileTest implements Runnable {
     private static boolean stopAll = false;
     private static int threadNumber = 0;
     private int myNumber = 0;

     public ArchiveFileTest () {
            myNumber = threadNumber;
            threadNumber++;
     }

     public static boolean setStopAll () {
            return setStopAll(true);
     }

     public static boolean setStopAll (boolean b) {
            stopAll = b;
            return stopAll;
     }

     public static String[] listFiles (File parentDir,final String ext1,final String ext2,final String ext3,final String ext4) {
            String allFiles[] = parentDir.list(new FilenameFilter() { 
                 public boolean accept(File pDir, String fName) {
                        if (fName.endsWith("."+ext1) || fName.endsWith("."+ext2) || fName.endsWith("."+ext3) || fName.endsWith("."+ext4)) return true;
                        else return false;
                 }
            });
            for (int i=0; i<allFiles.length; i++)
                 allFiles[i] = parentDir.getAbsolutePath() + File.separator +  allFiles[i];
            return allFiles;
     }

     public ZipFile getMyZipFile (File parentDir) {
            String fn[] = listFiles(parentDir, "jar", "zip", "war", "rar");
            int fileNum = myNumber % fn.length;
            ZipFile zFile = null;
            for (int i=0; i<fn.length; i++) {
                 String jFile = fn[(fileNum + i)%fn.length];
                 try {
                        zFile = new ZipFile(jFile);
                        break;
                 } catch  (IOException e) {
                     setStopAll();
                 }
            }
            return zFile;
     }

     public void doStuff() throws Exception {
            File dName = new File("/home/sqatest/chander/sample-files");
          final int N_TIMES = 15;
            final int N_FILES = 500;
          int counter = 0;
            int fCount  = 0;
            if (!dName.isDirectory() || !dName.exists()) {
                 System.err.println("The parent directory given should point to an existing directory...");
                 setStopAll();
                 return;
            }
          while (counter < N_TIMES) { 
                 ZipFile zipFile = getMyZipFile(dName);
                 if (zipFile == null) {
                        System.err.println("No zip file entry for the Thread-" + myNumber);
                        break;
                 }
                 try {
                        Enumeration <? extends ZipEntry> zipEntries = zipFile.entries(); 
                        fCount = 0;
                        ZipEntry ze = null;
                        while (zipEntries.hasMoreElements()) {
                             ze = zipEntries.nextElement();

                             if (ze.isDirectory()) continue; // if it is a directory go to next entry

                             InputStream is = zipFile.getInputStream(ze); 
                             fCount++;
                             int readCount = 0;
                             try {
                                    while(is.read((new byte[50])) != -1 && readCount != 200) readCount++;
                                    System.out.println("Successfully Read " + zipFile.toString());

                                    //is.close();
                             } catch (IOException e) {
                                    e.printStackTrace();
                             }
                             if (fCount == N_FILES) break;  // read maximum of N_FILES
                        }
                        if (stopAll) break;
                 } catch (Exception e) {
                     e.printStackTrace();
                 } finally {
                        counter++; 
                 }
          } 
     }

     public void run () {
            try {
                 doStuff();
            } catch (IOException e) {
                 e.printStackTrace();
                 setStopAll();
            } catch (Exception e) {
                 e.printStackTrace();
            }
     }

     public static void main (String[] args) throws Exception { 
          final int MAX_THREADS = 500;
          final int MAX_HOLDING_THREADS = 5;
            int loopCount = 0;
            Thread mainThread = Thread.currentThread();
            for (int m=0; ; m++) {
                 Thread t[] = new Thread[MAX_HOLDING_THREADS];
                 for (int n=0; n<t.length; n++) {
                        t[n] = new Thread(new ArchiveFileTest());
                        t[n].start();
                        if ((m+1)*(n+1)==MAX_THREADS) {
                             System.out.println("\n" + MAX_THREADS + " reached... \nMain Sleeping for some mins..."); 
                             loopCount++;
                             try {
                                    t[n].join();
                                    System.out.println("\nMain is back... (" + loopCount + ")");
                             } catch (InterruptedException e) {
                                    e.printStackTrace();
                                    setStopAll();
                             }
                             m = 0;
                        }
                 }
            }
     }
}
import java.io.*;
导入java.util.Enumeration;
导入java.util.jar.*;
导入java.util.zip.ZipEntry;
导入java.util.zip.ZipFile;
导入java.util.zip.ZipException;
导入java.io.FilenameFilter;
公共类ArchiveFileTest实现可运行{
私有静态布尔stopAll=false;
私有静态int threadNumber=0;
私有整数myNumber=0;
公共ArchiveFileTest(){
myNumber=螺纹编号;
threadNumber++;
}
公共静态布尔setTopAll(){
返回setStopAll(true);
}
公共静态布尔setTopAll(布尔b){
stopAll=b;
返回停止球;
}
公共静态字符串[]列表文件(文件parentDir、最终字符串ext1、最终字符串ext2、最终字符串ext3、最终字符串ext4){
字符串allFiles[]=parentDir.list(新文件名筛选器(){
公共布尔接受(文件pDir,字符串fName){
如果(fName.endsWith(“.”+ext1)| fName.endsWith(“.”+ext2)| fName.endsWith(“.”+ext3)| fName.endsWith(“.”+ext4))返回true;
否则返回false;
}
});
对于(int i=0;i
  • 在启动线程的类中,为正在运行的线程设置一个
    volatile
    计数器
  • 在线程构造函数中,传递对启动类的引用
  • 有一个同步方法,让线程通知启动类它们已经完成
  • 实例化并启动线程后,等待计数器变为0

    while(getRunningThreads() > 0) // getRunningThreads must be synchronized too
        Thread.sleep(500); // Check every half second.
    

  • 如果停止意味着终止,那么当所有线程(非守护进程特例)完成时,应用程序将停止。

    我认为应用程序永远不会停止。在主方法中有一个无限循环:

    for (int m=0; ; m++) {
        ....
    }
    
    请注意,在主体内部设置
    m=0
    不会打破循环,因此我认为即使没有文件,也不会结束。然后,它会连续读取目录中的所有zip/jar/war/rar文件(基于旋转计数器选择文件
    myNumber
    不是很容易维护),但不会退出循环

    若您的需求是使用多个线程读取ZIP文件,那个么我将采用另一种方式

  • 创建一组要查看的文件
  • 创建一个可创建5个线程的固定池
  • 迭代文件集并创建一个新的
    Runnable
    ,该方法执行Zip提取(尽管我不太清楚为什么读取Zip条目的前10000字节,然后不执行任何操作),并调用
    execute
    方法。该方法将使用线程池一次处理5个文件
  • 提交所有可运行程序后,使用
    shutdown
    方法,等待所有提交的任务完成,然后关闭线程池

  • 如果没有完整的代码,几乎不可能知道代码在做什么(例如,
    setStopAll()
    未定义)我们只能猜测线程是如何创建的,或者目录中有多少个文件。注意:除非设置了stopAll标志,否则每个线程将读取同一个文件15次。我已经用完整的代码更新了这个问题。一个小的OT注释。从设置器中删除boolean作为返回类型,将它们改为return void,因为您不使用return v值和标准是无效的。但这不能保证所有存档文件都已被读取。我想要实现的是在所有文件都已被读取时停止。我只浏览了一下您的代码,但从概念上讲,您不应该使用任何停止方法,布尔值或其他方法来停止您的程序,它应该自行停止,可能已经停止了?什么时候所有文件都已读取。不,它不会停止。我尝试只读取文件夹中的一个文件,但它一直在读取。我必须按住Ctrl+C组合键才能停止它。另外,不要忘记将计数器字段设置为volatile
    最好将计数器设置为AtomicInteger,否则,它的值将无法预测。