

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?