Java线程池实际场景问题!!面试必问 求解答

核心线程数7,最大线程数10,等待队列长20
有40个任务 如果40个任务在两秒内全部过来(每个任务执行时间大于两秒),执行拒绝策略,要拒绝多少任务?


答案是10个 
从测试结果可以看出,线程池会先将前7个任务(0-6)先放到核心线程池,然后 7 到 26 的任务来了之后被放入了等待队列中,后面id 27-29 因为等待队列满了,开始为这些任务创建新线程 直到到达最大线程数。从30 开始到来的任务都会被拒绝了。


测试代码:
public class MyRunnable implements Runnable{
    private String id;

    public MyRunnable(String id) {
        this.id = id;
    }

    @Override
    public void run() {
//        System.out.println(Thread.currentThread().getName() + " Start Time = " + new Date());
        processCommand();
//        System.out.println(Thread.currentThread().getName() + " End Time = " + new Date());
    }

    private void processCommand() {
        try {
            System.out.println("ID: " + this.id + " are in process");
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public String toString() {
        return this.id;
    }
}


public class ThreadPoolExecutorDemo {
    public static final int CORE_POOL_SIZE = 7;
    public static final int MAX_POOL_SIZE = 10;
    public static final int QUEUE_CAPACITY = 20;
    public static final long KEEP_ALIVE_TIME = 1L;


    public static void main(String[] args) {

        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                CORE_POOL_SIZE,
                MAX_POOL_SIZE,
                KEEP_ALIVE_TIME,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(QUEUE_CAPACITY),
                new ThreadPoolExecutor.AbortPolicy());

        for (int i = 0; i < 40; i++) {
            Runnable worker = new MyRunnable("" + i);
            try {
                executor.execute(worker);
            } catch (Exception e) {
                System.out.println("Execute ID:" + i + " got exception with details: " + e.getMessage());
            }

        }

        executor.shutdown();
        while (!executor.isTerminated()) {
        }
        System.out.println("Finished all threads");
    }
}

#java##面试题目#
全部评论
10个,队列里阻塞的任务和Worker线程正在处理的任务应该是分开算的,这里是源码。 int c = ctl.get(); if (workerCountOf(c) < corePoolSize) { if (addWorker(command, true)) return; c = ctl.get(); } if (isRunning(c) && workQueue.offer(command)) { int recheck = ctl.get(); if (! isRunning(recheck) && remove(command)) reject(command); else if (workerCountOf(recheck) == 0) addWorker(null, false); } else if (!addWorker(command, false)) reject(command);
1 回复 分享
发布于 2021-08-03 01:15
我猜测是10个?首先有7个线程去核心线程池中运行,然后再来的线程发现核心线程池已经满了就在队列中等待,这时候队列中可以等待10个线程,这就是17个线程了,还剩13个线程要来。再来的线程发现核心线程池满了就去看队列,队列也满了就判断当前是否已经达到了最大的maximumsize,发现不满然后把7扩成10,所以正在执行的有10个,队列中有20个,一共30个,再来的就被拒绝。以上是我的猜测,不知道对不对
1 回复 分享
发布于 2021-08-04 20:16
30个
点赞 回复 分享
发布于 2021-08-02 07:45
顶一下 没人吗
点赞 回复 分享
发布于 2021-08-02 15:29
10个
点赞 回复 分享
发布于 2021-08-02 16:16
3?
点赞 回复 分享
发布于 2021-08-02 17:57
是10还是7?
点赞 回复 分享
发布于 2021-08-02 21:51
答案是10个 线程池会先将前7个任务(0-6)先放到核心线程池,然后 7 到 26 的任务来了之后被放入了等待队列中,后面id 27-29 因为等待队列满了,开始为这些任务创建新线程 直到到达最大线程数。从30 开始到来的任务都会被拒绝了。
点赞 回复 分享
发布于 2021-08-05 02:45
9  或  10 吧 AbortPolicy: 丢弃任务并抛出RejectedExecutionException异常。  DiscardPolicy:丢弃任务,但是不抛出异常。  DiscardOldestPolicy:丢弃队列最前面的任务,然后重新提交被拒绝的任务  CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务
点赞 回复 分享
发布于 2021-08-14 15:31

相关推荐

评论
1
6
分享
牛客网
牛客企业服务