案例: 创建两个线程,一个线程用来计算1000以内所有的素数(素数也称为质数,除了1和它本身以外不再有其他因数)之和,另一个线程用来计算1000以内所有的水仙花数(水仙花数指一种三位数,其各个数之立方和等于该数)之和。
要求:分别使用Runnable和Callable实现。
//计算素数之和的线程类
class PrimeRunable implements Runnable {
//用来判断是否是素数
private boolean isPrime(int num) {
for (int i = 2; i <= Math.sqrt(num); i++) {
if (num % i == 0) { //说明发生了整除
return false;
}
}
return true;
}
@Override
public void run() {
//线程结束,直接输出计算结果。
long sum =0;
//1-1000以内所有的素数,1不是
for(int i=2;i<=1000;i++){
if(isPrime(i)){
sum+=i;
try {
//输出找到的素数:
System.out.println("找到素数:" + i);
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println("1-1000以内所有的素数之和是:" + sum);
}
}
//计算水仙花之和的线程类
class FlowerRunnable implements Runnable {
//首先判断一下,水仙花数必须是三位数
private boolean isFlower(int num){
if(num<100||num>=1000){
return false;
}
//分别取出这个数字,个位,十位,百位。
//123==》3 123%10---》3
// 2 123/10---》12%10--》2
// 1
int gw = num%10;
int sw = num/10%10;
int bw = num/100;
if((Math.pow(gw,3)+Math.pow(sw,3)+Math.pow(bw,3))==num){
return true;
}
return false;
}
@Override
public void run() {
long sum = 0;
for(int i=1;i<=1000;i++){
if(isFlower(i)){ //说明是水仙花是数
sum += i;
try {
//输出找到的素数:
System.out.println("找到一个水仙花:" + i);
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println("1-1000以内的水仙花数之和是:" + sum);
}
}
public class PrimeNumberThreadDemo {
public static void main(String[] args) {
PrimeRunable primeRunable = new PrimeRunable();
FlowerRunnable flowerRunnable = new FlowerRunnable();
Thread primeTh = new Thread(primeRunable);
Thread flowerTh = new Thread(flowerRunnable);
primeTh.start();
flowerTh.start();
}
}
运行结果:
1-1000以内的水仙花数之和是:1301
1-1000以内所有的素数之和是:76127
import java.util.concurrent.*;
//实现计算1-1000以内所有的素数之和的Callable
class PrimeCallable implements Callable<Long> {
//用来判断是否是素数
private boolean isPrime(int num) {
for (int i = 2; i <= Math.sqrt(num); i++) {
if (num % i == 0) { //说明发生了整除
return false;
}
}
return true;
}
@Override
public Long call() throws Exception {
//线程结束,直接输出计算结果。
long sum = 0;
//1-1000以内所有的素数,1不是
for (int i = 2; i <= 1000; i++) {
if (isPrime(i)) {
sum += i;
try {
//输出找到的素数:
System.out.println("找到素数:" + i);
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
return sum;
}
}
//实现计算1-1000以内所有的水仙花数值的Callable
class FlowerCallable implements Callable<Long> {
//首先判断一下,水仙花数必须是三位数
private boolean isFlower(int num) {
if (num < 100 || num >= 1000) {
return false;
}
//分别取出这个数字,个位,十位,百位。
int gw = num % 10;
int sw = num / 10 % 10;
int bw = num / 100;
if ((Math.pow(gw, 3) + Math.pow(sw, 3) + Math.pow(bw, 3)) == num) {
return true;
}
return false;
}
@Override
public Long call() throws Exception {
long sum = 0;
for (int i = 1; i <= 1000; i++) {
if (isFlower(i)) { //说明是水仙花是数
sum += i;
try {
//输出找到的素数:
System.out.println("找到一个水仙花:" + i);
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
return sum;
}
}
public class PrimeNumberCallableDemo {
//阻塞式关闭线程池。
public static void awaitAfterShutdown(ExecutorService threadPool) {
threadPool.shutdown();
try {
if (!threadPool.awaitTermination(200, TimeUnit.SECONDS)) {
threadPool.shutdownNow();
}
} catch (InterruptedException ex) {
threadPool.shutdownNow();
Thread.currentThread().interrupt();
}
}
public static void main(String[] args) throws Exception {
PrimeCallable primeCallable = new PrimeCallable();
FlowerCallable flowerCallable = new FlowerCallable();
ExecutorService executor1 = Executors.newFixedThreadPool(2);
Future<Long> primeFuture = executor1.submit(primeCallable);
Future<Long> flowerFuture = executor1.submit(flowerCallable);
Long primeSum = primeFuture.get();
Long flowerSum = flowerFuture.get();
System.out.println("1-1000以内的素数之和是:" + primeSum);
System.out.println("1-1000以内所有的水仙花数之和是:" + flowerSum);
awaitAfterShutdown(executor1); //等获得返回值,并且打印结果之和,使用非阻塞式方式来关闭一个线程池。
}
}
运行结果:
1-1000以内的水仙花数之和是:1301
1-1000以内所有的素数之和是:76127