如果一个结果为假,则停止多个FutureTask

问题描述

此程序有什么问题?如果其中之一返回false作为结果,我想立即停止所有FutureTask。参见第100行及其后的内容。我列出了将来的任务。然后,我实例化执行程序服务并添加所有任务。然后,我执行任务并遍历任务列表,以检查一个任务是否返回false

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

public class PrimeIterator {
    private boolean longBased = true;
    private long startLong;
    private BigInteger startBI;

    public PrimeIterator(BigInteger start) {
        if (start.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) {
            longBased = false;
        }
        if (longBased) {
            startLong = start.longValue();
        } else {
            startBI = start;
        }
    }

    public BigInteger nextPrime() {
        BigInteger b;
        while (true) {
            if (longBased) {
                if (isPrime(startLong)) {
                    b = BigInteger.valueOf(startLong);
                    increase();
                    return b;
                }
            } else {
                if (isPrime(startBI)) {
                    b = startBI;
                    increase();
                    return b;
                }
            }
            increase();
        }
    }

    private boolean isPrime(long toTest) {
        if (toTest % 2 == 0) {
            return false;
        }
        long sqrt = (long) Math.sqrt(startLong);
        for (long i = 3; i <= sqrt; i += 2) {
            if (toTest % i == 0) {
                return false;
            }
        }
        return true;
    }

    private static class MyTask implements Callable<Boolean> {

        private final BigInteger toTest;
        private final BigInteger part;
        private final int multiplier;
        private static volatile boolean hasFalseResult;

        private MyTask(BigInteger toTest,BigInteger part,int multiplier) {
            this.toTest = toTest;
            this.part = part;
            this.multiplier = multiplier;
            hasFalseResult = false;
        }

        @Override
        public Boolean call() throws Exception {
            BigInteger from = part.multiply(BigInteger.valueOf(multiplier)).add(BigInteger.valueOf(3));
            BigInteger to = part.multiply(BigInteger.valueOf(multiplier + 1)).add(BigInteger.valueOf(3));
            System.out.println("starting: " + toTest + " " + from + " " + to + " " + toTest.sqrt());
            return isPrime(toTest,from,to);
        }

        private boolean isPrime(BigInteger b,BigInteger from,BigInteger to) {
            for (BigInteger i = from; to.compareTo(i) > 0; i = i.add(BigInteger.TWO)) {
                if (hasFalseResult) {
                    return false;
                }
                if (b.mod(i).compareTo(BigInteger.ZERO) == 0) {
                    hasFalseResult = true;
                    return false;
                }
            }
            return true;
        }

    }

    private boolean isPrime(BigInteger toTest) {
        // if (toTest.isProbablePrime(5)) {
        if (toTest.mod(BigInteger.TWO).compareTo(BigInteger.ZERO) == 0) {
            return false;
        }
        BigInteger sqrt = toTest.sqrt();
        BigInteger part = sqrt.divide(BigInteger.valueOf(10)).add(BigInteger.ONE);
        List<FutureTask<Boolean>> taskList = new ArrayList<FutureTask<Boolean>>();
        for (int i = 0; i < 10; i++) {
            taskList.add(new FutureTask<>(new MyTask(toTest,part,i)));
        }
        ExecutorService executor = Executors.newFixedThreadPool(3);
        for (FutureTask<Boolean> futureTask : taskList) {
            executor.execute(futureTask);
        }
        try {
            for (FutureTask<Boolean> futureTask : taskList) {
                if (!futureTask.get()) {
                    return false;
                }
            }
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
            return false;
        }
        return true;
        // }
        // return false;
    }

    private void increase() {
        if (longBased) {
            if (startLong == Long.MAX_VALUE) {
                longBased = false;
                startBI = BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE);
            } else {
                startLong++;
            }
        } else {
            startBI = startBI.add(BigInteger.ONE);
        }
    }

    public static void main(String[] args) {
        PrimeIterator pi = new PrimeIterator(BigInteger.valueOf(1));
        for (int i = 0; i < 20; i++) {
            System.out.println(pi.nextPrime());
        }

        pi = new PrimeIterator(BigInteger.valueOf(Long.MAX_VALUE - 10));
        for (int i = 0; i < 5; i++) {
            System.out.println(pi.nextPrime());
        }
    }
}

解决方法

FutureTasks在后​​台线程中运行。一旦返回false,您的isPrime()方法将立即返回。但这不会停止其他FutureTask的运行,因为它们在单独的线程中运行。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...