Java并发编程(五) - 线程池(中)

2020-07-14  本文已影响0人  ElliotG

1. 拒绝策略

超负荷了怎么办? 拒绝策略

ThreadPoolExecutor最后一个参数指定了拒绝策略。
也就是当任务数量超过了系统实际承载能力时,该如何处理。
这个时候就要用到拒绝策略。
拒绝策略通常用于系统超负荷运行时,也就是线程池中的线程已经用完了,无法继续为新任务服务,同时,
等待队列中也已经满了,再也塞不下新任务了。

JDK内置了四种拒绝策略:

MyTask.java

public class MyTask implements Runnable {
    @Override
    public void run() {
        System.out.println(System.currentTimeMillis() + ":Thread ID:" + Thread.currentThread().getId());
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

RejectThreadPoolDemo.java

public class RejectThreadPoolDemo {
    public static void main(String[] args) throws InterruptedException {
        MyTask task = new MyTask();
        ExecutorService es = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingDeque<Runnable>(10),
                Executors.defaultThreadFactory(),
                new RejectedExecutionHandler() {
                    @Override
                    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                        System.out.println(r.toString() + " is discarded");
                    }
                });
        for (int i=0;i<Integer.MAX_VALUE;i++) {
            es.submit(task);
            Thread.sleep(10);
        }
    }
}

上述代码定义了一个有5个常驻线程,并且最大线程数也是5个的线程池。
这个线程池拥有一个10个容量的等待队列。
而且,自定义了拒绝策略,将丢弃的任务信息进行打印。

 

2. 自定义线程创建(ThreadFactory)

线程池中的线程从哪里来?

线程池是为了线程复用,避免线程的频繁创建。
那么,最开始的那些线程从哪里来?
答案是:
ThreadFactory(线程工厂)

ThreadFactory是一个接口,它只有一个方法newThread(Runnable r),用来创建线程。
因此,我们需要实现它来自定义自己的线程工厂。

通过自定义线程工厂来自定义线程创建有很多优势:

示例代码:

public class MyTask implements Runnable {
    @Override
    public void run() {
        System.out.println(System.currentTimeMillis() + ":Thread ID:" + Thread.currentThread().getId() + " Start...");

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(System.currentTimeMillis() + ":Thread ID:" + Thread.currentThread().getId() + " End!");
    }
}

public class CustomThreadFactoryDemo1 {
    public static void main(String[] args) {
        int threadNum = 5;

        MyTask task = new MyTask();

        // 自定义线程工厂
        ExecutorService es = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.MILLISECONDS,
                new SynchronousQueue<>(),
                new ThreadFactory() {
                    @Override
                    public Thread newThread(@NotNull Runnable r) {
                        Thread t = new Thread(r);
                        t.setDaemon(true);
                        System.out.println("create " + t);
                        return t;
                    }
                });

        for (int i = 0; i < threadNum; i++) {
            es.submit(task);
        }

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

运行结果:
create Thread[Thread-0,5,main]
create Thread[Thread-1,5,main]
create Thread[Thread-2,5,main]
create Thread[Thread-3,5,main]
create Thread[Thread-4,5,main]
1594989090932:Thread ID:14 Start...
1594989090932:Thread ID:13 Start...
1594989090933:Thread ID:16 Start...
1594989090933:Thread ID:17 Start...
1594989090932:Thread ID:15 Start...
1594989091955:Thread ID:16 End!
1594989091955:Thread ID:13 End!
1594989091955:Thread ID:15 End!
1594989091955:Thread ID:17 End!
1594989091955:Thread ID:14 End!

上一篇下一篇

猜你喜欢

热点阅读