java
1import java.util.Collections; 2import java.util.LinkedList; 3import java.util.List; 4import java.util.Scanner; 5 6public class CountPal extends Thread{ 7 8 private static Long count = 0L; 9 private static List<CountPal> threads = Collections.synchronizedList(new LinkedList<>()); 10 11 private final long from; 12 private final long until; 13 14 public CountPal(long from, long until) { 15 this.from = from; 16 this.until = until; 17 } 18 19 @Override 20 public void run() { 21 long total = 0L; 22 for(long i = from; i < until; i++){ 23 if(checkPal(i)){ 24 total += i; 25 } 26 } 27 synchronized (count) { 28 count += total; 29 } 30 threads.remove(this); 31 } 32 33 private boolean checkPal(long i){ 34 String str = Long.toString(i); 35 int m = 0; 36 int n = str.length() - 1; 37 while(m < n){ 38 if(str.charAt(m) != str.charAt(n)){ 39 return false; 40 } 41 m++; 42 n--; 43 } 44 return true; 45 } 46 47 48 49 public static void main(String[] args) { 50 try (Scanner s = new Scanner(System.in)) { 51 long max = s.nextLong(); 52 for(long x = 1; x <= max; x += 10000){ 53 CountPal temp = new CountPal(x, Math.min(x + 10000, max + 1)); 54 threads.add(temp); 55 temp.start(); 56 } 57 // すべてのスレッドが終了するまで待つ 58 while(threads.size() != 0){ 59 try { 60 System.out.println(threads.size()); // 現在のスレッド数ダンプ 61 Thread.sleep(1000); 62 } catch (InterruptedException e) { } 63 } 64 System.out.println(count); 65 } 66 } 67 68}
ある数を入力し、その数以下の回文数(121のように左右どちらから読んでも同じになる数)の合計を求めるプログラムです(本題のプログラム問題を解くために作成した、時間はかかるが確実に正しい答えを出すための副産物的なプログラムです)。
適当な数(10000)で分割し、スレッドを生成して手分けしてカウントするようなプログラムなのですが、「すべてのスレッドが終了するまで待つ」という部分が上手く書けません。
現状、生成したThreadをListに詰め、終了する際にThreadがListから自身を取り除くようにし、ListのThreadが0になるまで待つ、という構成なのですが、0になってからも1秒未満とはいえ余計に待つことになります。
調べるとwait()やnotifyAll()を使うらしいことはわかったのですが、何に対してこのメソッドを使えばいいのかがわかりません。
また、Listを使う以外の方法がもしありましたら教えてください。
回答4件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/04/29 12:19 編集
2016/04/30 04:31
2016/04/30 05:49
2016/05/02 03:44 編集
2016/05/02 01:44
2016/05/03 14:29