lab23
subdirectory of your personal repo, the other submits a file report.txt
in the lab23
subdirectory of your personal repo.lab23
and add a class Primes
with this method:
public static Runnable printPrimes(BigInteger start, long length) { return () -> { BigInteger n = start; for (long i = 0; i < length; i++) { if (n.isProbablePrime(100)) System.out.println(n); n = n.add(BigInteger.ONE); } }; }What does the method do? (Note:
n.isProbablePrime(100)
returns true if n
is a prime, with error probability < 2-100. Assume for now that means that n
is certainly a prime.)Runnable
objects like this:
Runnable r1 = printPrimes(new BigInteger("1000000000000000"), 10000); Runnable r2 = printPrimes(new BigInteger("2000000000000000"), 10000);
ExecutorService service = Executors.newFixedThreadPool(2); ... ... service.shutdown();Run your program. What happens?
System.out
. We need to use a Callable
since a Runnable
can't return a value. Make a function countPrimes
that returns a Callable<Long>
.Callable<Long> c1 = countPrimes(new BigInteger("1000000000000000"), 500_000); Callable<Long> c2 = countPrimes(new BigInteger("1000000000500000"), 500_000);
ExecutorService
as in the preceding slide. You'll get two Future<Long>
. Call
System.out.println(f1.get()); System.out.println(f2.get());before calling
service.shutdown();Run the program. What does it print?
isProbablePrime
method sounds as if it was guessing, but it is actually perfectly deterministic. For a given n
, the call n.isProbablePrime(100)
will always give the same result. It is just that the result may be wrong. The chance for that is 2-100 or about 10-30. The probability of you being struck by lightning in a given year is about 10-6. Now imagine yourself and four other people—your lab buddy, another pair of buddies, and your long-suffering professor. The probability of all of us five being struck by lightning in the same year is about 10-30. If that what keeps you up at night, then you should definitely worry about n.isProbablePrime(100)
giving you the wrong answer.service.submit
long start = System.currentTimeMillis(); ... long end = System.currentTimeMillis(); System.out.println("Milliseconds: " + (end - start));Run the program and write down the number of milliseconds. Then change
Executors.newFixedThreadPool(2);
to Executors.newFixedThreadPool(1);
, which means that only one thread is available. Run the program again. You should notice a delay between the printouts of the two counts. What milliseconds do you get? private static long nonprime = 0;In the
countPrimes
method, add
else nonprime++;when a number isn't a prime. After printing each result, add a call
System.out.println(nonprime);Run the program a few times. What results do you get? Which values are the same, and which are different in each run?