- 创建线程的方式
B站经典视屏 https://www.bilibili.com/video/BV1u7411t7G1/?p=7&spm_id_from=pageDriver&vd_source=349c5319b954e1b190c0fe9d9dedc4c6
继承Thread,实现Runnable接口
run()方法和start()方法区别
run方法是主线程里的方法,和主线程一个线程
而start方法执行时会新起一个线程
3. 线程和线程池性能对比
为什么线程池比较快?
下图三种方式哪种最快呢?
3. newCacheThreadPool原理 同步队列
核心线程数0,非核心线程数无限大,会随着任务多少,无限创建线程
线程的复用:任务完成后,会继续去完成别的任务
4. newFixedThreadPool 链表队列
核心和非核心线程数都是传进来的
最大线程数包含核心线程数,也就是都是核心员工,没有非核心员工
5. newFixedThreadPool
6. 为什么阿里不推荐使用自带的线程池工具类
第一种 无限创建线程会导致CPU100%,但是并不会内存溢出
第二种、第三种是采用的LinkedBlockedQueue,队列无限长,可以无限存放
任务无限堆积,会导致内存溢出OOM
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
private static final ExecutorService THREAD_WORK_POOL = new ThreadPoolExecutor(2 * CPU_COUNT, 3 * CPU_COUNT + 1,
0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(2048),
new ThreadFactoryBuilder().setNameFormat("clean-coopMercProvCd-pool-%d").build(), new ThreadPoolExecutor.AbortPolicy());
-
拒绝策略
-
线程池执行的先后顺序(提交优先级和执行优先级)
核心区域和非核心区域的任务先执行,最后在执行队列里的任务,虽然队列里的任务比非核心区域先放进来排队
看源码,task不为空就会执行,再判断getTask()也就是从队列中获取任务
9. execute()方法和submit()方法区别?
二者的接收参数不一样
Execute()方法只能接收Runnable类型的参数,而submit()方法可以接收Callable、Runnable两种类型的参数。Callable类型的任务是可以返回执行结果的,而Runnable类型的任务不可以返回执行结果。
Callable是JDK 1.5加入的执行目标接口,作为Runnable的一种补充,允许有返回值,允许抛出异常。Runnable和Callable的主要区别为:Callable允许有返回值,Runnable不允许有返回值;Runnable不允许抛出异常,Callable允许抛出异常。
submit()提交任务后会有返回值,而execute()没有
execute()方法主要用于启动任务的执行,而任务的执行结果和可能的异常调用者并不关心。submit()方法也用于启动任务的执行,但是启动之后会返回Future对象,代表一个异步执行实例,可以通过该异步执行实例去获取结果。
submit()方法自身并不会传递结果,而是返回一个Future异步执行实例,处理过程的结果被包装到Future实例中,调用者可以通过Future.get()方法获取异步执行的结果。通过submit()返回的Future对象获取异步执行结果,演示代码如下