在JAVA中使用多线程池读取文本文件

时间:2015-06-06 10:25:38

标签: java multithreading threadpool

我想读取一个包含6行整数的文件,用逗号分隔。每次我使用线程池时,它们都会读取同一行。我希望每个线程都快速输出一行,将其保存在文件中。在此方法之后,mergeSort将对它们进行排序。

 public class myclass2 extends myclass {
 public static void main(String [] arg){
 final myclass obj=new myclass();

        System.out.println("Enter number of threads you want to instantiate\n");
        Scanner handle=new Scanner (System.in);
        final int no=handle.nextInt();
         ExecutorService threadPool = Executors.newFixedThreadPool(no);
         for (int i = 0; i < no; i++) 
         {
             System.out.println(i);
                threadPool.submit(new Runnable() {
                     public void run() {
                         obj.runProgram(no);
                     }
                 });
         }
         System.out.println("Before merge sort in myclass 2");
         obj.mergesort();
             // once you've submitted your last job to the service it should be shut down
             threadPool.shutdown();



        handle.close();
}
}

runProgram方法的代码如下。它从Data.txt读取,快速排序,然后将其保存在文件中。

   public void runProgram(int no)
   {

    Scanner handleforfile=null;
    String recFromFile=null;
    FileWriter x=null;
    try {
        int check=0;
        check++;
        if(check<2)
        {
            File fileobj= new File("Data.txt");
            handleforfile=new Scanner(fileobj);

            FileWriter handle=new FileWriter("ThreadingData.txt",true);
            BufferedWriter bwhandle1=new BufferedWriter(handle);
            x=handle;
            handle.close();
        }
                 if(handleforfile.hasNext())
                 {
                    for(int i=0;i<check;i++)
                    {
                     recFromFile=handleforfile.nextLine();//reads the line req
                    }
                     System.out.println("Rec line from file"+recFromFile);//rec data from file
                     String[] numberStrs = recFromFile.split(",");//convert it into now int[]
                        int[] numbers = new int[numberStrs.length];
                        for(int ik = 0;ik < numberStrs.length;ik++)
                        {
                           numbers[ik] = Integer.parseInt(numberStrs[ik]);
                           System.out.println(numbers[ik]);

                        }

                        System.out.println("converted into int[]");
                        quickSort(numbers,0,numbers.length-1);
                        String temp=Arrays.toString(numbers);
                        System.out.println(temp);
                        BufferedWriter bwhandle=new BufferedWriter(x);
                        try {
                            bwhandle.write(temp.substring(1,temp.length()-1));//avoids brakets////////////////
                            bwhandle.write('\n');
                            //bwhandle.flush();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            System.out.println("here in myclass");
                            e.printStackTrace();
                        }
                 }//end if
                 else
                 {
                     System.out.println("returning");
                     return;
                 }


    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        System.out.println("here in myclass2");
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        System.out.println("here in myclass3");
        e.printStackTrace();
    }

2 个答案:

答案 0 :(得分:0)

这里的问题是每个线程创建一个单独的扫描器实例,指向文件,因此每个都将从第一行开始,

File fileobj= new File("Data.txt");
handleforfile=new Scanner(fileobj);

如果您希望每个线程读取相应的行,则只创建一个扫描器实例并协调线程访问。

答案 1 :(得分:0)

您需要在主线程中读取文件,将其拆分为行,将每行放到另一个线程进行排序,然后再将其合并。

没有必要对文件进行多线程读取,因为线程必须同步,在这种情况下,没有足够的数据来使其值得。

如果你有大块的线条,你可以让你的主线程找到块边界,然后告诉子线程从哪里开始读取,但是主线程可以更快地完成所有的读取(否则你冒险阅读文件两次)。

这基本上是 map-reduce

您正在考虑输入阅读器阶段。见MapReduce#Input_reader