线程池ThreadPoolExecutor

线程池ThreadPoolExecutor

创建好多个线程,放入线程池中,使用时直接获取引用,不使用时放回池中。可以避免频繁创建销毁、实现重复利用

  线程池中只有1个线程,省去了创建和关闭的时间:newSingleExecutor();
  ExecutorService pool1 = Executors.newSingleThreadExecutor();
   线程池中有固定数量的线程:newFixedThreadPool
  ExecutorService pool2 = Executors.newFixedThreadPool(10);
        //线程池中线程的数量可以增加也可以减少:newCachedTreadPool()
  ExecutorService pool3 = Executors.newCachedThreadPool();
        //定时任务 用来执行大量的定时任务
  ExecutorService pool4 = Executors.newScheduledThreadPool(10);

new ThreadPoolExcutor(corePoolSize,maximumPoolSize,keepAliveTime,Unit,workQueue,handier)

对于线程池进行Runnable任务用pool.execute(runnable);

package pool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 使用线程池执行大量的Runnable命令
 */
public class TestThreadPool1 {
    public static void main(String[] args) {
        //创建线程池
        
      ExecutorService pool3 = Executors.newCachedThreadPool();
          //使用线程池执行大量的Runnable任务
        for (int i = 0; i < 20; i++) {
            Runnable runnable = new MyRunnable(i);
            //new Thread(runnable).start();
            pool3.execute(runnable);
        }
        //关闭线程池
        pool3.shutdown();
    }


}
class MyRunnable implements Runnable {
private int i;

    public MyRunnable(int i) {
        this.i = i;
    }

    @Override
    public void run() {
        System.out.println("任务"+i+"开始");
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("任务"+i+"结束");
    }
}

使用线程池执行大量Callable任务

运行Callable任务时,callable具有返回值

使用线程使用pool.sumits()

package pool;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.*;

/**
 * 使用线程池执行大量的Callable任务
 *
 */
public class TestThreadPool2 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
    //1创建一个线程池
        ExecutorService pool3 = Executors.newFixedThreadPool(10);
        
        //2使用线程池执行大量的callable任务
        List<Future> futureList=new ArrayList<Future>();
        for (int i = 0; i < 20; i++) {
            final int n = i;
            Callable<Integer> task = new Callable<Integer>() {

                @Override
                public Integer call() throws Exception {  //匿名内部类
                    //匿名内部类是局部内部类,可以直接使用内部类中的局部变量,
                     //变量必须要用final修饰
                    //
                    System.out.println("线程开始:" + n);
                    Thread.sleep(3000);//睡眠3秒
                    int result = new Random().nextInt(10);
                    System.out.println("线程结束:" + n);
                    return result;
                }

            };
            Future<Integer> future = pool3.submit(task);
            //int result = future.get();
//            System.out.println(result);
            futureList.add(future);

        }
        for (int i = 0; i < 20; i++) {
            Future future1 = futureList.get(i);
            System.out.println(future1.get());
        }
        //3关闭线程池
        pool3.shutdown();
    }
}
//
//class MyCallable implements Callable<Integer>{
//    @Override
//    public Integer call() throws Exception {
//        return new Random().nextInt(10);//获取10以内的整数
//    }
//}

这里在使用在匿名内部类中sleep()三秒,不能在for循环后直接使用int result = future.get();

因为使用future().get();由于get()得到命令要求得到数字,但是在产生数字前会睡眠3秒,从而在获得结果这等待随机数产生,从而将for循环阻塞

线程池API 总结

  1. Executor:线程池顶级接口,只有一个方法
  2. ExecutorService:真正的线程池接口
    1. void execute(Runnable command) :执行任务/命令,没有返回值,一般用来执行Runnable
    2. <T> Future<T> submit(Callable<T> task):执行任务,有返回值,一般又来执行Callable
    3. void shutdown() :关闭线程池
  3. AbstractExecutorService:基本实现了ExecutorService的所有方法
  4. ThreadPoolExecutor:默认的线程池实现类
  5. ScheduledThreadPoolExecutor:实现周期性任务调度的线程池
  6. Executors:工具类、线程池的工厂类,用于创建并返回不同类型的线程池                   
    1. Executors.newCachedThreadPool():创建一个可根据需要创建新线程的线程池
    2. Executors.newFixedThreadPool(n);  创建一个可重用固定线程数的线程池
    3. Executors.newSingleThreadExecutor() :创建一个只有一个线程的线程池
    4. Executors.newScheduledThreadPool(n):创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。

 

线程池ThreadPoolExecutor参数

public ThreadPoolExecutor(int corePoolSize,

          int maximumPoolSize,

          long keepAliveTime,

          TimeUnit unit,

          BlockingQueue<Runnable> workQueue,

          ThreadFactory threadFactory,

          RejectedExecutionHandler handler) {

}

    • corePoolSize:核心池的大小
      • 默认情况下,创建了线程池后,线程数为0,当有任务来之后,就会创建一个线程去执行任务。
      • 但是当线程池中线程数量达到corePoolSize,就会把到达的任务放到队列中等待。
    • maximumPoolSize:最大线程数。
      • corePoolSize和maximumPoolSize之间的线程数会自动释放,小于等于corePoolSize的不会释放。当大于了这个值就会将任务由一个丢弃处理机制来处理。
    • keepAliveTime:线程没有任务时最多保持多长时间后会终止
      • 默认只限于corePoolSize和maximumPoolSize间的线程
    • TimeUnit
      • keepAliveTime的时间单位
    • BlockingQueue
      • 存储等待执行的任务的阻塞队列,有多种选择,可以是顺序队列、链式队列等。
    • ThreadFactory
      • 线程工厂,默认是DefaultThreadFactory,Executors的静态内部类
    • RejectedExecutionHandler
      • 拒绝处理任务时的策略。如果线程池的线程已经饱和,并且任务队列也已满,对新的任务应该采取什么策略。
      • 比如抛出异常、直接舍弃、丢弃队列中最旧任务等,默认是直接抛出异常。

                    1、CallerRunsPolicy:如果发现线程池还在运行,就直接运行这个线程

                     2、DiscardOldestPolicy:在线程池的等待队列中,将头取出一个抛弃,然后将当前                       线程放进去。

                     3、DiscardPolicy:什么也不做

                     4、AbortPolicy:java默认,抛出一个异常:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值