1

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

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");

    }

}

问题是它不起作用。有人可以指出我正确的方向吗?谢谢。

4

3 回答 3

1

您使用Runnable. 你现在有几个问题:

  1. 您当前fileReader为这两个文件创建 1 和 1 个线程,但您的意图是为每个文件创建一个单独的线程。
  2. 您正在尝试使用一些静态变量在线程之间进行通信,但您不会在打印变量之前等待工作线程完成。

要解决您的第一个问题,您需要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. 使用线程编程时,最好与其他线程共享尽可能少的状态(变量)。

此外,还有一个非常方便的Executor框架,它为处理线程提供了更好的 API。一个巨大的胜利是允许您轻松地从线程返回一个值,您可以使用它来返回读取的行数。

较大的变化是:

  • 您的类实现Callable<Integer>而不是Runnable. 这里的<Integer>部分意味着你希望你的线程返回一个整数(即文件中的行数)
  • 代替void run(),您定义Integer call(),它返回文件中的行数。
  • 您无需直接创建Threads,而是将要完成的任务提交Executor.
  • 而不是join()一起 ing 线程,只需get()从 a 中返回线程的返回值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();
于 2013-11-06T00:40:47.490 回答
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();
于 2013-11-06T00:03:00.743 回答
0

您需要等待线程完成其工作。你太早打印你的resault。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);
        }
    }
于 2013-11-06T00:10:43.097 回答