2012-03-18 11 views
3

ReaderとWorkerという2つのJavaクラスがあります。 Readerはテキストファイルから文字列を読み込み、これらの文字列をワーカーに渡して、これらの文字列をツリーにソートします。方法、それが呼び出すことにより、労働者の1に文字列を渡す -Java:スレッドを別のスレッドに渡すスレッド

私のリーダーは、実行()内のテキストファイルから文字列を読み込み
 try {  

     /* Create and run worker processes. */ 
     workers = new TrieWorker[numberOfWorkers]; 
     for(int i = 0; i < numberOfWorkers; i++) 
     { 
      workers[i] = new TrieWorker(this); 
      new Thread(workers[i]).run(); 
     } 

     /* Create and run reader process. */ 
     reader = new TrieReader(this, filename);       
     new Thread(reader).run(); 

    } catch(Exception e) { 
     e.printStackTrace(); 
    } 

は:だから私は、ワーカー・スレッドの数と1リーダースレッドを作成します

workers[i].add(string); 

作業者は基本的にこのメソッドが呼び出されるまで何もしません。だから私は読者がこのパラメータをWorkersの1人に渡した直後にテキストファイルから読み続けるのだろうかと疑問に思いますか?または、Workerが文字列で処理された後にのみ、このメソッドから戻りますか?言い換えれば、あるスレッドが別のスレッドにパラメータを渡すと、スレッド渡しパラメータが何らかの回答を返さない限り、両方とも独自の処理を継続しますか?

あなたは私が何を意味するか知っていることを願っています。説明するのは本当に難しいです。

編集:良い回答ありがとう!ここではリーダークラスのコードは次のとおりです。

private static int numberOfNextWorker = 0; 

    public void run() 
{ 
    System.out.println("Reader run."); 

    try { 
     System.out.println("Reading " + filename); 
     read(); 
    } catch (Exception ex) { 
     ex.printStackTrace(); 
    } 
} 

public void read() throws Exception 
{ 
    File file = new File(filename); 
    Scanner reader = new Scanner(file); 

    if(file.canRead() == false) 
     throw new Exception("file " + filename + " cannot be read."); 

    long totalLength = file.length(); 

    while(reader.hasNextLine()) 
    { 

      String text = reader.nextLine();   
      numberOfLines++; 

      /* Passes the work on to workers. */ 
      if(numberOfNextWorker == (numberOfWorkers - 1)) 
       numberOfNextWorker = 0; 
      else 
       numberOfNextWorker++; 

      workers[numberOfNextWorker].add(text); 
     } 
} 

そして、ここで労働者:

public void run() 
{ 
    System.out.println("Worker run."); 
} 

void add(String text) 
{ 
    numberOfStrings++; 
    char[] chars = text.toCharArray(); 

    int i = 0; 
    Node node = new Node(); 

    while (chars.length > i) { 
     node.value = chars[i]; 
     node = node.children; 
     i++; 
    } 
} 

それは私が、私はあなたが言ったことを理解だと思う:)まだ賢明な何もしていません。私は並行性に関するこの本をたくさん読んでおり、紙の演習をいくつか行っていますが、それほどコードを書くことを試みていません。

+1

読み取りメソッドは、addメソッドが返っても読み込みを続けます。それが作業者による文字列の処理の終わりに対応するかどうかは、addメソッドが何をするかによって異なります。コードを私たちに教えてください。 –

答えて

1

リソースと呼ばれる第3のクラスが必要です。スレッドは共有リソースを通じて通信します。プロデューサー - 消費者と考えるあなたの労働者はsortedReultに追加します。

public class Resource{ 
    Queue<String> semaphore = new LinkedList<String>(); 
    Queue<String> sortedResult = new LinkedList<String>(); 

    public synchronized addStrings(List<String> words){//for reader 
    semaphore.addAll(words); 
    notify(); 
    }// 

    public synchronized String getString(){//for workers 
    while(semaphore.isEmpty()) 
     try{ wait();} 
     catch(InterruptedException e){} 
    return semaphore.remove(); 
    } 
} 

ところで、run()を呼んでいると、ロジックが分かります。しかしJavaでは、start()を呼び出してstart()にrun()を呼び出さなければなりません。

+0

外部からセマフォキューにアクセスするにはどうすればよいですか、それともpublic staticと宣言する必要がありますか? – yerassyl

6

いつでも新しいスレッドを開始するのではなく、同じスレッドでrun()メソッドを呼び出すだけであることに注意してください。

次の例のように、新しいスレッドを作成するためにstart()にコールする必要があります。

new Thread(workers[i]).start(); 

代わりのスレッドは作業があなたの実装に依存し続ける方法、具体的

new Thread(workers[i]).run(); 

2

Worker.addの呼び出しがブロックされているため、add()が完了するまで待機します。これはすべてスレッド1で実行されます.Worker.addが作業のリストに作業を追加するだけで、run()メソッドで作業(独自のスレッドで実行)が処理される場合。

これは古典的な消費者/生産者の問題です。 (ブロッキング)キューが役立ちます。

関連する問題