线程池

线程池:三大方法、7大参数、4种拒绝策略

java.util.conrent
类 Executors

三大方法:

 

 

1.public static ExecutorService newSingleThreadExecutor()
创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程。
(注意,如果因为在关闭前的执行期间出现失败而终止了此单个线程,那么如果需要,一个新线程将代替它执行后续的任务)。可保证顺序地执行各个任务,并且在任意给定的时间不会有多个线程是活动的。与其他等效的 newFixedThreadPool(1) 不同,可保证无需重新配置此方法所返回的执行程序即可使用其他的线程。

java.util.concurrent
接口 Executor
所有已知子接口
ExecutorService, ScheduledExecutorService,实现类:ThreadPoolExecutor

ExecutorService 接口 中的这个方法是继承于Excutor 接口     

void execute(Runnable command) 在未来某个时间执行给定的命令。 //Executors 工具类,三大方法

//Executors 工具类,三大方法
public class ExecutorsSingleThreadDemo {

    public static void main(String[] args) {
        ExecutorService threadPool = Executors.newSingleThreadExecutor();//单线程
        //创建线程都用线程池的方式: es.execute()
        try {
            for(int i = 0;i<3;i++) {
                final int temp = i;
                threadPool.execute(()->{
                    System.out.println(Thread.currentThread().getName()+"=>"+temp);
                });
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            //线程池用完,程序结束,要记得关闭            
            threadPool.shutdown();
        }
        
    }
}
结果:

pool-1-thread-1=>0
pool-1-thread-1=>1
pool-1-thread-1=>2

2.public static ExecutorService newFixedThreadPool(int nThreads)

创建一个可重用固定线程集合的线程池,以共享的无界队列方式来运行这些线程。如果在关闭前的执行期间由于失败而导致任何线程终止,那么一个新线程将代替它执行后续的任务(如果需要)。 

public class FixedThreads {

    public static void main(String[] args) {
        ExecutorService threadPool =  Executors.newFixedThreadPool(5);
        try {
            for(int i = 0;i<=8;i++) {
                final int temp = i;
                threadPool.execute(()->{
                    System.out.println(Thread.currentThread().getName()+" => "+ temp);
                });
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            //使用完要记得关闭
            threadPool.shutdown();
        }
    }
}
结果:会开启5条线程跑

pool-1-thread-2 => 1
pool-1-thread-1 => 0
pool-1-thread-3 => 2
pool-1-thread-1 => 6
pool-1-thread-2 => 5
pool-1-thread-1 => 8
pool-1-thread-3 => 7
pool-1-thread-5 => 4
pool-1-thread-4 => 3

 

3.public static ExecutorService newCachedThreadPool()
创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。对于执行很多短期异步任务的程序而言,这些线程池通常可提高程序性能。调用 execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。因此,长时间保持空闲的线程池不会使用任何资源。注意,可以使用 ThreadPoolExecutor 构造方法创建具有类似属性但细节不同(例如超时参数)的线程池。

遇强则强,遇弱则弱

public class CachedThread {

    public static void main(String[] args) {
        ExecutorService threadPool = Executors.newCachedThreadPool();
        try {
            for(int i = 0;i<10;i++) {
                final int temp = i;
                threadPool.execute(()->{
                    System.out.println(Thread.currentThread().getName()+"=>"+temp);
                });
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            //线程池用完,程序结束,要记得关闭            
            threadPool.shutdown();
        }
    }
}
结果:开启了十个线程

pool-1-thread-1=>0
pool-1-thread-2=>1
pool-1-thread-3=>2
pool-1-thread-5=>4
pool-1-thread-4=>3
pool-1-thread-6=>5
pool-1-thread-7=>6
pool-1-thread-8=>7
pool-1-thread-10=>9
pool-1-thread-9=>8

 

七大参数:

 

    public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }


    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }



    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

 使用ThreadPoolExecutor创建线程池,注意七大参数。

package JUC.ThreadPool;

import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPoolExecutorDemo {

    public static void main(String[] args) {
        RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
        //7个参数:
        //一开始默认是开启两个线程
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2,5,3,TimeUnit.SECONDS,new LinkedBlockingQueue(3),
                                      Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy()); try { //当线程数达到2+blockingQueue里面的数据的时候,则会开始增加线程 //最大承载值为:队列值加上最大线程数 //当达到最大承载值以后,则会使用拒绝策略,四大拒绝策略。 for(int i = 1;i<=5;i++) { final int temp = i; threadPool.execute(()->{ System.out.println(Thread.currentThread().getName()+" => "+ temp); }); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { //使用完要记得关闭 threadPool.shutdown(); } } }

四种拒绝策略:

线程池的最大的线程数如何去设置:

 

//获取CPU核数的代码:        
        System.out.println(Runtime.getRuntime().availableProcessors());
posted @ 2020-11-18 15:14  Joyce502  阅读(152)  评论(0)    收藏  举报