マルチスレッドプログラムからのファイル出力
VM:java1.4.2
OS:WindowsXp
マルチスレッドのプログラムで、一つのファイルにテキストの出力を行うところで、うまくいかないところがあります。
<ソースファイル>
import java.io.*;
import java.util.*;
import java.text.*;
public class ThreadIppai {
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
Thread thread = new ThreadHontai();
thread.start();
}
}
}
class ThreadHontai extends Thread {
public void run() {
try {
for (int i = 0; i < 500; i++) {
BufferedWriter bw = new BufferedWriter(new FileWriter(
"D:\\out.log", true));
String msg = (String) Values.ht.get(String.valueOf((int) (Math.random() * 10)).substring(0, 1)) + "\n";
bw.write(msg, 0, msg.length());
bw.flush();
bw.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Values {
public static Hashtable ht = new Hashtable();
static {
// ht.put("0", "0000000000");
// ht.put("1", "1111111111");
// ht.put("2", "2222222222");
// ht.put("3", "3333333333");
// ht.put("4", "4444444444");
// ht.put("5", "5555555555");
// ht.put("6", "6666666666");
// ht.put("7", "7777777777");
// ht.put("8", "8888888888");
// ht.put("9", "9999999999");
ht.put("0", "0");
ht.put("1", "11");
ht.put("2", "222");
ht.put("3", "3333");
ht.put("4", "44444");
ht.put("5", "555555");
ht.put("6", "6666666");
ht.put("7", "77777777");
ht.put("8", "888888888");
ht.put("9", "9999999999");
}
}
<問題点>
ファイルに出力された結果をみると、テキストの一部が欠けていたり、改行がされない行があったりします。
おそらく、同期処理を加えてないからだとは思うのですが・・・。(質問に続く)
<質問1>
テキストの一部が欠けたり、改行されない行が発生する原因はなぜでしょうか?
たとえば、「0」と「11」を出力するとき、同時に複数のスレッドが書き込んだ場合、「101」となるのは、なんとなく分かります。
しかし、これが「01」のように、出力されるべき文字が出力されないという現象が発生してます。
<質問2>
htにputする値の文字列長が、すべて異なっていますが、これをコメントアウトされている行のように、すべて同じ文字列長に
した場合、上記の問題は発生しなくなります。
この原因はなんでしょうか?
<質問3>
この問題を、ThreadHontaiクラスのfor文の中だけの変更で解決することは可能でしょうか?(極力手を加えずに)
synchronizedブロックの追加でいけるのかと思いましたが、試行錯誤の結果うまくいきませんでした。
以上、よろしくお願いします。
補足
「待つ」という処理が必要だったんですね。 調べてみたらjoin()というメソッドでスレッドの待機が できるとのことだったので以下のようにしてみたところうまくいきました。ありがとうございました。 public static void main(String[] args) throws InterruptedException { String[] listUrls = {"http://www.yahoo.co.jp", "http://www.google.co.jp", "http://httpd.apache.org"}; ExThread[] threads = new ExThread[listUrls.length]; for(int i=0; i<listUrls.length; i++) { threads[i] = new ExThread(listUrls[i]); threads[i].start(); } // 全てのスレッドが終了するのを待つ for(int i=0; i<listUrls.length; i++) { threads[i].join(); } System.out.println("★★終了★★"); }