阿⾥⼆⾯被问JavaThreadPool线程池,看完这篇,⼀招怒怼
⾯试官
线程池的优势
线程池做的⼯作主要是控制运⾏的线程数量,处理过程中将任务放⼊队列,然后在线程创建后启动这些任务,如果线程数量超过了最⼤数量,超出的线程排队等候,等待其他线程执⾏完毕,再从队列中取出任务来执⾏
线程池的特点
线程复⽤、控制最⼤并发数、管理线程
降低资源消耗。重复利⽤已创建的线程,降低创建和销毁线程的开销
提⾼响应速度。当任务到达时,任务可以不需要等待线程创建就能⽴刻执⾏
提⾼线程的可管理性。使⽤线程池可以对线程进⾏统⼀的分配、调优和监控
1 线程池的⽅法
java线程池创建的四种执⾏长期任务性能好,创建⼀个线程池,⼀池有N个固定的线程,可以控制线程最⼤并发数,有固定线程数的线程池ExecutorService threadPool = wFixedThreadPool(N);
单个任务执⾏,它只会使⽤单个⼯作线程,⼀池⼀线程
ExecutorService threadPool = wSingleThreadExecutor();
执⾏短期异步任务,可缓存线程池,线程池根据需要创建新线程,但在先前构造的线程可以复⽤,也可灵活回收空闲的线程,可扩容的池
ExecutorService threadPool = wCachedThreadPool();
周期性线程池;⽀持定时及周期性任务执⾏
ExecutorService threadPool = wScheduledThreadPool();
(1) newFixedThreadPool
可以控制线程最⼤并发数的线程池:
public class FixedThreadPool {
private static AtomicInteger num = new AtomicInteger(0);
private static ExecutorService executorService = wFixedThreadPool(2);
public static void main(String[] args) {
countSum c= new countSum();
//将coutSum作为Task,submit⾄线程池
for (int i = 0; i < 2; i++) {
executorService.submit(c);
}
//Task执⾏完成后关闭
executorService.shutdown();
}
static class countSum implements Runnable{
@Override
public void run() {
for (int i = 0; i < 500; i++) {
try{
System.out.println("Thread - "+Thread.currentThread().getName()+" count= "+ AndIncrement()); Thread.sleep(100);
}catch (Exception e){
e.printStackTrace();
}
}
}
}
}
结果:
阿⾥⼆⾯被问Java ThreadPool线程池,看完这篇,⼀招怒怼⾯试官
(2) newSingleThreadExecutor
只会使⽤唯⼀的⼯作线程执⾏任务的线程池:
private static AtomicInteger num = new AtomicInteger(0);
private static ExecutorService executorService = wSingleThreadExecutor();
public static void main(String[] args) {
//将coutSum作为Task,submit⾄线程池
for (int i = 0; i < 2; i++) {
executorService.submit(new countSum());
}
//Task执⾏完成后关闭
executorService.shutdown();
}
static class countSum implements Runnable{
@Override
public void run() {
for (int i = 0; i < 500; i++) {
try{
System.out.println("Thread - "+Thread.currentThread().getName()+" count= "+ AndIncrement()); Thread.sleep(100);
}catch (Exception e){
e.printStackTrace();
}
}
}
}
}
结果:
阿⾥⼆⾯被问Java ThreadPool线程池,看完这篇,⼀招怒怼⾯试官
(3) newScheduledThreadPool
传参值为corePoolSize⼤⼩,⽀持定时及周期性任务执⾏
延期执⾏⽰例:调⽤schedule⽅法,三个参数:Task,Delay,TimeUnit
// corePoolSize = 2
private static ScheduledExecutorService service = wScheduledThreadPool(2);
public static void main(String[] args) {
System.out.println("Thread - "+Thread.currentThread().getName()+" BEGIN "+ new Date());
service.schedule(new print(),5, TimeUnit.SECONDS);
service.shutdown();
}
static class print implements Runnable{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try{
System.out.println("Thread - "+Thread.currentThread().getName()+" Delay 5 second and sleep 2 second "+ new Date()); Thread.sleep(2000);
}catch (Exception e){
e.printStackTrace();
}
}
}
}
}
结果:
阿⾥⼆⾯被问Java ThreadPool线程池,看完这篇,⼀招怒怼⾯试官
定时执⾏⽰例:调⽤scheduleAtFixedRate⽅法,四个参数:Task,initialDelay,Period,TimeUnit
public class ScheduledThreadPool {
// corePoolSize = 1
private static ScheduledExecutorService service = wScheduledThreadPool(1);
public static void main(String[] args) {
System.out.println("Thread - "+Thread.currentThread().getName()+" BEGIN "+ new Date());
service.scheduleAtFixedRate(new print(),5,3,TimeUnit.SECONDS);
}
static class print implements Runnable{
@Override
public void run() {
System.out.println("Thread - "+Thread.currentThread().getName()+" Delay 5 second and period 3 second "+ new Date());
}
}
}
结果:
阿⾥⼆⾯被问Java ThreadPool线程池,看完这篇,⼀招怒怼⾯试官
(4) newCachedThreadPool
可缓存线程池,如果线程池长度超过处理需要,回收空闲线程,若⽆可回收,则新建线程。即若前⼀个任务已完成,则会接着复⽤该线程:public class CachedThreadPool {
private static AtomicInteger num = new AtomicInteger(0);
private static ExecutorService service = wCachedThreadPool();
public static void main(String[] args) {
countSum c = new countSum();
for (int i = 0; i < 3; i++) {
try {
service.submit(c);
Thread.sleep(1000);
}catch (Exception e){
e.printStackTrace();
}
}
service.shutdown();
}
static class countSum implements Runnable{
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("Thread - "+Thread.currentThread().getName()+" countSum= "+AndIncrement());
}
}
}
}
结果:Thread.sleep(1000)即sleep⼀秒,上个任务完成可继续复⽤该线程,不需要创建新的线程
阿⾥⼆⾯被问Java ThreadPool线程池,看完这篇,⼀招怒怼⾯试官
若将Tread.sleep(1000)注释掉,你会发现有3个线程在跑
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论