Java在使用线程时读取两个文件中的行数

时间:2013-11-05 23:48:20

标签: java multithreading file count

我昨天发布了这个,但我的代码很乱。我要做的是计算两个单独文件的行数,并在每个文件的单独线程中打印行号。 这就是我所拥有的:

import java.io.File;
import java.util.Scanner;

public class fileReader implements Runnable
{    
    static int count = 0;
    static int count1 = 0;

    public void run()
    {
        try
        {
        Scanner file1 = new Scanner(new File("filetest1.txt"));
        Scanner file2 = new Scanner(new File("filetest2.txt"));

        while (file1.hasNextLine()) 
        {
              count++;
              file1.nextLine();
        }

        while (file2.hasNextLine()) 
        {
              count1++;
              file2.nextLine();
        }
     }
        catch(Exception e)
        {
            count = -1;
            count1 = -1;
        }
}

    public static void main(String[] args) 
    {
            (new Thread(new fileReader())).start();
            System.out.println("File one has " + count + " lines");
            System.out.println("File two has " + count1 + " lines");

    }

}

问题在于它不起作用。有人能指出我正确的方向吗?感谢。

3 个答案:

答案 0 :(得分:1)

您使用Runnable走在正确的轨道上。你现在有几个问题:

  1. 您目前为这两个文件创建了1 fileReader个1个帖子,但您的目的是为每个文件创建一个单独的主题。
  2. 您正在尝试使用一些静态变量在线程之间进行通信,但是您不是在打印变量之前等待工作线程完成。
  3. 要解决您的第一个问题,您需要为每个文件创建一个新的Runnable和一个新线程。 (我要将您的fileReader课程重命名为LineCounter,以避免与标准库中类似名称的FileReader混淆。

    class LineCounter implements Runnable {
        private final File file;
    
        public LineCounter(File file) {
            this.file = file;
        }
    
        public void run() {
            // Count lines in file.
        }
    }
    

    现在您可以创建2个单独的LineCounter对象,一个用于计算每个文件中的行。

    Thread thread1 = new Thread(new LineCounter(new File("filetest1.txt")));
    Thread thread2 = new Thread(new LineCounter(new File("filetest2.txt")));
    thread1.start();
    thread2.start();
    

    至于你的第二个问题,你的主线程必须(产生这两个其他线程的那个)需要等待它们完成才能读取包含每个文件中行数的变量。您可以使用join()

    指示主线程等待另一个线程完成
    thread1.join();
    thread2.join();
    // Print your variables.
    

    话虽如此,使用静态变量进行线程之间的通信充其量是可疑的:

    1. 要真正做到这一点,您必须synchronize访问这些变量,或者将其声明为volatile
    2. 使用线程编程时,最好与其他线程共享尽可能少的状态(变量)。
    3. 此外,存在非常方便的Executor框架,它提供了一个更好的API来处理线程。一个很大的好处是,它允许您轻松地从线程返回一个值,您可以使用该值返回读取的行数。

      重大变化是:

      • 您的班级实施Callable<Integer>而不是Runnable。这里的<Integer>部分意味着你希望你的线程返回一个整数(即文件中的行数)
      • 而不是void run(),您定义Integer call(),它返回文件中的行数。
      • 不是直接创建Thread,而是提交要完成Executor的任务。
      • 而不是join()一起使用线程,只需get()来自Future的线程的返回值。

      转换为Executor样式,解决方案类似于

      class LineCounter implements Callable<Integer> {
          private final File file;
      
          public LineCounter(File file) {
              this.file = file;
          }
      
          public Integer call() {
              // Count number of lines in file.
              return numLines;
          }
      }
      

      在主线程中:

      ExecutorService executor = Executors.newFixedThreadPool(2);
      Future<Integer> future1 = executor.submit(new LineCounter(new File("file1.txt")));
      Future<Integer> future2 = executor.submit(new LineCounter(new File("file2.txt")));
      Integer file1Lines = future1.get();
      Integer file2Lines = future2.get();
      

答案 1 :(得分:0)

public class fileReader1 implements Runnable
{    
    static int count = 0;
    public void run()
    {
        try
        {
        Scanner file1 = new Scanner(new File("filetest1.txt"));
         ............
         ............
         ............
    }
}

public class fileReader2 implements Runnable
{    
    static int count = 0;
    public void run()
    {
        try
        {
        Scanner file1 = new Scanner(new File("filetest2.txt"));
         ............
         ............
         ............
   }
}

现在您可以启动两个线程并开始同时读取文件:

Thread t1=new Thread(new fileReader1());
Thread t2=new Thread(new fileReader2());

t1.start();
t2.start();

答案 2 :(得分:0)

您需要等待线程完成其工作。 你太早打印你的故事。 thr.join()阻止你的程序直到thr完成。

    public static void main(String args[]) {
        try {
            Thread thr = new Thread(new fileReader());

            thr.start();
            thr.join();

            System.out.println("File one has " + count + " lines");
            System.out.println("File two has " + count1 + " lines");
        } catch (InterruptedException ex) {
            Logger.getLogger(fileReader.class.getName()).log(Level.SEVERE, null, ex);
        }
    }