java 线程池基本用法

1,线程与进程的基本区别

->进程:
    拥有自己一整套变量,数据之间不可见。创建/撤销-开销很大。
->线程:
    共享数据,共享变量存储在主存中(Main Memory),每个现场有自己私有的本地内存(Local Memory),本地内存存的是主存的一个副本,与进程相比,线程很"轻量",创建/撤销-开销比较小

2,实现一个线程的几种方式

class MyThread extends Thread {
    @Override
    public void run() {
        //要执行的业务代码
    }

}


class MyRunner implements Runnable {
    @Override
    public void run() {
        //要执行的业务代码
    }   
}

//可以用线程池来执行
class MyCallable implements Callable<Object>{
    @Override
    public Object call() throws Exception{
        //要执行的业务代码
        return null;
    }   
}

3,Thread.start和Thread.run

Thread.start代表开启一个线程,如果这个线程获取到了CPU资源,处于运行态的话,就会执行业务代码,很显然开启线程,不一定会执行业务代码。

但是Thread.run,代表直接调用的run方法,作为普通的方法调用。

4,ThreadPoolExecutor七个参数的基本用法

ThreadPoolExecutor(
    int corePoolSize,
    int maxiNumPoolSize,
    long keepAliveTime,
    TimeUnit unit,
    BlockingQueue<Runnable> workQueue,
    THreadFactory tHreadFactory,
    RejectedExecutionHandler rejectedExecutionHandler
);

corePoolSize : 核心线程数,也就是线程池创建出来去执行用户任务的线程个数,线程会调用任务的run方法(注意是调用run方法,而不是start开启线程)。如果用户提交的任务个数小于这个值,任务将会马上被执行(有点绝对的说法,但是意思上也差不多)。
maxiNumPoolSize : 线程池能够创建线程的最大值,什么时候回动用这个值?就是当用户提交的任务大于了corePoolSize,且超过了工作队列workQueue可容纳的最大值,就会在corePoolSize这个的基础上再创建线程去处理任务(也就是任务量太多,线程池会加大处理的速度),但是总的线程数目不会超过maxiNumPoolSize。如果当前线程池创建的线程最大化了,workQueue满了,就会拒绝用户任务的加入。
workQueue :用来保存用户提交的任务队列,用的是阻塞队列(阻塞队列有什么特性,请看看JAVA的API以及源码)。
tHreadFactory : 线程池的线程工厂类,用来创建线程用的,一般就用线程池默认的好了。
rejectedExecutionHandler : 这个参数代表线程池拒绝用户添加任务的处理策略。有四种处理方式:ThreadPoolExecutor.AbortPolicy(直接丢弃任务,抛出异常,默认),ThreadPoolExecutor.DicardPolicy(直接丢弃任务,不抛出异常),ThreadPoolExecutor.DicardOldestPolicy(丢弃最前面的任务,然后尝试重新执行任务),ThreadPoolExecutor.CallerRunsPolicy(由调用现场处理任务,成功与否听天由命)

5,线程池用法举例

在使用线程池来并发执行任务时,需要考虑任务完成一次需要的时间,任务量多少,已经任务空闲时间需要多级,仔细评估以后,设置适合的参数,才能让线程池更好的为业务代码服务。

猜你喜欢

转载自blog.csdn.net/zhao_zhengZZ/article/details/85338007