← 返回首页
JavaSE基础教程(一百零四)
发表时间:2022-03-01 20:30:40
创建线程案例

案例: 创建两个线程,一个线程用来计算1000以内所有的素数(素数也称为质数,除了1和它本身以外不再有其他因数)之和,另一个线程用来计算1000以内所有的水仙花数(水仙花数指一种三位数,其各个数之立方和等于该数)之和。

要求:分别使用Runnable和Callable实现。

1.Runnable实现方式

//计算素数之和的线程类
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

2.Callable实现方式

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