[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[jfriends-ml 13369] The Art of Multiprocessor の Fig 1.1 のプログラム(素数判定)



 高橋(徹)です。

「The Art of Multiprocessor」Fig 1.1のプログラム(断片)について
オンラインで入手可能なサンプルには含まれていなかったので、スレッド
の復習がてら作ってみました。
素数判定ロジックはJavaに標準では備わっていないようなので、ぐぐって
超簡単な実装を使ってますが、どうやら時間がかかりすぎ、終わる気配が
ありません。(各スレッドにつき10の9乗回(10億回)実行するので)

そこで、コマンドラインから、指数を指定できるようにしました。

とりあえずメールにソースを添付します。




import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.CountDownLatch;

/**
 * ‘f”‚ðŒ©‚Â‚¯‚¾‚·ƒNƒ‰ƒXB
 * ‘ÐuThe Art of Multiprocessor Programmingv1Í Fig 1.1‚ÌŽÀ‘•
 *
 * Last updated: 2010-09-13T14:24:28Z
 */
public class PrimeFinder implements Runnable {
    private CountDownLatch startLatch;
    private CountDownLatch stopLatch;
    private int id;
    private int power;
    private int numFound;

    public PrimeFinder(
        final int id, final int power, 
        final CountDownLatch start, final CountDownLatch stop
    ) {
	this.id = id;
        this.power = power;
	startLatch = start;
        stopLatch = stop;
    }

    public void run() {
	try {
	    startLatch.await();
            long block = (long)Math.pow(10, power);
            System.out.println("Now start id:" + id);
            long startTime = System.nanoTime();
            for (long i = (id * block) + 1; i <= (id + 1) * block; ++i) {
                if (isPrime(i)) {
                    numFound++;
                }
            }
            long stopTime = System.nanoTime();
            System.out.println(
                "id:" + id + " founds " + numFound + " primes in " +
                nanosec2sec(stopTime - startTime) + " seconds."
            );
	} catch (InterruptedException e) {
	    System.err.println("PrimeFinder[id:" + id + "] has interrupted" +
			       ", so exit this thread.");
	    Thread.currentThread().interrupt();
	    return;
	} finally {
            stopLatch.countDown();
        }
    }

    /**
     * ‘f””»’胁ƒ\ƒbƒh.
     */
    public static boolean isPrime(long number) {
	for (int i = 2; i < number - 1; ++i) {
	    if ( number % i == 0) {
		return false;
	    }
	}
        return true;
    }

    public int nanosec2sec(long nanos) {
	return (int)(nanos / 1000000000);
    }

    /**
     * ƒGƒ“ƒgƒŠEƒ|ƒCƒ“ƒg‚ð’ñ‹Ÿ‚·‚émainƒƒ\ƒbƒhB
     * ƒRƒ}ƒ“ƒhƒ‰ƒCƒ“ˆø”‚Æ‚µ‚āAŒvŽZ”͈͂̎w”‚ðŽó‚¯Žæ‚éBÈ—ªŽž‚Í9B
     */
    public static final void main(final String[] args) {
	final int numThreads = 10;
	Executor executor = Executors.newFixedThreadPool(numThreads);
	CountDownLatch startLatch = new CountDownLatch(1);
	CountDownLatch stopLatch = new CountDownLatch(numThreads);
        int power = 9;
        if (1 <= args.length) {
            power = Integer.parseInt(args[0]);
        }
        System.out.println(
            "Start finding prime number concurrently, with " + numThreads + 
            " threads, each searches 10^" + power + " ranges."
        );
	for (int i = 0; i < numThreads; ++i) {
	    PrimeFinder task = new PrimeFinder(i, power, startLatch, stopLatch);
	    executor.execute(task);
	}
	startLatch.countDown();
	try {
	    stopLatch.await();
            System.out.println("Finish searching prime numbers");
	} catch (InterruptedException e) {
	    System.err.println("Interrupted while waiting tasks");
	}
        System.exit(0);
    }
}