2017-06-25 7 views
-2

私はマルチスレッドを使用してファイルを読むことに関していくつかの答えを読んだだけでなく、効率は非常に悪いが、それでもなお学習のために私はマルチスレッドを使用してファイル大量のファイルは、1つのスレッドで読み取られるレコードはほとんどなく、別のスレッドによって読み取られる必要があります。マルチスレッドを使用してtxtファイルを読む

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

public class QueueThread implements Runnable { 

    int count=0; 
    private int start; 
    private int end; 

    public QueueThread(int start,int end) { 
     this.start=start; 
     this.end=end; 


    } 

    public void run() { 

     for(int i=start;i<end;i++) {   

     try { 
      Scanner read = new Scanner (new File("userinfo.txt")); 
      read.useDelimiter(",|\n"); 
      String mobile,recharge; 

      while(read.hasNext()) 
      {     
       mobile = read.next(); 
       recharge =read.next(); 

       ArrayList<String> words = new ArrayList<String>(); 
       words.add(mobile+recharge); 

       count++; 

       System.out.println("mobile no.:"+ mobile); 
       System.out.println("recharge amount:"+ recharge); 
       System.out.println("count:"+ count); 
      } 

      read.close(); 

     } catch (FileNotFoundException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     } 
    } 
} 

Control.java:ここ

public class Control { 
    public static void main(String args[]) throws InterruptedException 
    { 
     QueueThread r1=new QueueThread(0,15); 
     QueueThread r2=new QueueThread(15,30); 
      Thread t1 =new Thread(r1); 
      Thread t2 =new Thread(r2); 

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

      t1.join(); 
      t2.join(); 


    } 
} 

ノーいくつかのランダムな10桁のファイルUSERINFO.TXTを読んでいます。いくつかの番号。各スレッドは、ファイル全体を読み取るのではなく、1つのスレッドの最初の15エントリを読み込み、別のスレッドの他の14エントリを読み込み、並行してファイルを読み込むというモットーを破ると思います。 また、抽出されたデータをArrayListに格納して、それ以降の操作を実行しようとしています。私は別のスレッドで同時に

電流出力

mobile no.:9844794101 
recharge amount:43 
mobile no.:9844794101 
count:1 
recharge amount:43 
count:1 
mobile no.:9844749102 
recharge amount:54 
mobile no.:9844749102 
recharge amount:54 
count:2 
count:2 

そしてそうしたファイルを読み込むためにいくつかの方法を実際に行う必要があるのです

USERINFO.TXT

9844794101,43 
9844749102,54 
9844741903,55 
9844741094,33 
9844741095,87 
9844741068,32 
9844974107,53 
8848897101,343 
8848891702,345 
8848891063,34 
8848849104,64 

+2

最近、マルチスレッドの読み取りに関する質問が非常に多い理由はわかりません(右の関連する質問を参照してください)。 I/Oハードウェア(ディスク、データバスなど)はボトルネックでありCPUではないため、通常はあまり得られません。 – Henry

+1

学習のために*何*? 1つのスレッドで何百万もの行を読み取ることができます。問題をスレッドに分割することで、知的にも何を得ようとしていますか? – EJP

+0

マルチスレッドについて知りたければ、比較的小さなファイルを読むことは正しい問題ではありません。 –

答えて

1

学習のためであれば、2つのスレッドで1つのScannerオブジェクトを使用するだけです。隣接する単語のペアを読み込んで結合する必要があるので、2つのスレッドを動作させる方法を考えなければなりません。

最も簡単な方法は、すべてのスレッドが 'synchronized(scannerObject){...}'を使用していくつかの単語を読み取るようにすることです。もちろん、パフォーマンスはシングルスレッドソリューションより悪くなります。他の解決策では、同期化を避けることができる。 AtomicIntegerをカウンターとして使用して、次の単語のカウンターからConcurrentSkipListMapに単語を格納するとします。

私は古典的なアプローチは、新しい単語を読むことができるファイルの真ん中に正確なポイントを知ることだと思います。その後、最初のスレッドは最初から '中間'の位置にファイルを読み込み、2番目のスレッドは '中間'の位置から最後まで読み取ることができます。例えば、 Make BufferedReader start from the middle of a .txt file rather than the beginning?

0

代わりの

Scanner read = new Scanner (new File("userinfo.txt")); 

あなたはInputStream sおよびReaderの詳細については、

InputStream inputStream = new BufferedInputStream(new FileInputStream(new File("userinfo.txt")))); 
inputStream.skip(<number of bytes to start of first desired record>); 
Scanner read = new Scanner(inputStream); 
// then make sure you only read as many records as you need 

検索のようなものを使用する必要があります。

問題は、あなたのレコード形式与えられ、(あなただけではない,または|のために、改行を探す必要がありますが)、ファイルの前の部分を読まずskipへの正しい引数を取得する方法はありません。 startendをレコード数ではなくバイト数にすることができますが、レコードの途中に着地してしまい、注意する必要があることを認識する必要があります。

最終的にArrayListを整列させたい場合、2番目のスレッドは、最初のスレッドの挿入が完了するまで待たなければなりません。そうでない場合は、アクセスを同期させるか、代わりにhttps://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentLinkedQueue.htmlを使用してください。

関連する問題