Java多线程(三)——线程池及定时器
创始人
2024-05-28 16:45:37
0

线程池就是一个可以复用线程的技术。前面三种多线程方法就是在用户发起一个线程请求就创建一个新线程来处理,下次新任务来了又要创建新线程,而创建新线程的开销是很大的,这样会严重影响系统的性能。线程池就相当于预先创建好几个线程(招聘几个打工人),来分配之后要处理的任务(干活)。

线程池的接口:ExecutorService

线程池对象

  1. 使用ExecutorService的实现类ThreadPoolExecutor自创建一个线程池对象

可以看到有7个参数,通过这些参数设置线程池的规模和特征。ExecutorService的常用方法有execute、submit、shutdown、shutdownNow。

  1. ThreadPoolExecutor构造器的参数:

  1. 1:指定线程池的线程数量(核心线程): corePoolSize

  1. 2:指定线程池可支持的最大线程数: maximumPoolSize

  1. 3:指定临时线程的最大存活时间: keepAliveTime

  1. 4:指定存活时间的单位(秒、分、时、天): unit

  1. 5:指定任务队列: workQueue

  1. 6:指定用哪个线程工厂创建线程: threadFactory

  1. 7:指定线程忙,任务满的时候,新任务来了怎么办: handler,默认丢弃任务并抛出RejectedExecutionException异常。

  1. ThreadPoolExecutor创建线程池对象

ExecutorService pool=new ThreadPoolExecutor(3,6,8, TimeUnit.SECONDS,new ArrayBlockingQueue<>(6), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
  1. 线程池处理Runnable任务 ——pool.execute()

首先实现Runnable接口,重写run方法。然后创建MyRunnable任务对象,只不过这里不是把MyRunnable任务对象交给Thread处理,而是使用线程池pool的execute()方法。

class myRunnable implements Runnable{@Overridepublic void run() {for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + " ——>" + i);}try {System.out.println(Thread.currentThread().getName() + " —— 休眠");Thread.sleep(2000);System.out.println(Thread.currentThread().getName() + " —— 启动");} catch (InterruptedException e) {e.printStackTrace();}}
}
//Runnable target=new myRunnable();pool.execute(target);
  1. 线程池处理Callable任务 ——pool.submit()

定义类实现Callable接口,重写call方法,封装要做的事情。然后把Callable对象进行submit(),并且可以返回执行后的结果。

class myCallable implements Callable {private int n;public myCallable(int n) {this.n = n;}@Overridepublic String call() throws Exception {int s=0;for (int i = 0; i < n; i++) {s+=n;}return Thread.currentThread().getName()+" 1+...+" + n +", 子线程执行结果: "+s;}
}
//Callable myCallable=new myCallable(10);Future f1 = pool.submit(myCallable);System.out.println(f1.get());
  1. 使用Executors(线程池的工具类)调用方法返回不同特点的线程池对象

Executors的底层其实也是基于线程池的实现类ThreadPoolExecutor创建线程池对象的。Executors得到线程池对象的常用方法:

方法

说明

弊端

public static ExecutorService newCachedThreadPool()

线程数量随着任务增加而增加,如果线程任务执行完毕且空闲了一段时间则会被回收掉。

允许创建的线程数量最大上限是Integer.MAX_VALUE,非常非常大,

可能会创建大量线程,出现OOM错误( 内存溢出 java.lang.OutOfMemoryError )

public static ExecutorService newFixedThreadPool(int nThreads)

创建固定线程数量的线程池,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程替代它。

允许请求的任务队列长度是Integer.MAX_VALUE,可能会堆积大量请求,出现OOM错误

public static ExecutorService newSingleThreadExecutor ()

创建只有一个线程的线程池对象,如果该线程出现异常而结束,那么线程池会补充一个新线程。

允许请求的任务队列长度是Integer.MAX_VALUE,可能会堆积大量请求,出现OOM错误

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)

创建一个线程池,可以实现在给定的延迟后运行任务,或者定期执行任务。

允许创建的线程数量最大上限是Integer.MAX_VALUE,

可能会创建大量线程,出现OOM错误

Executors不适合做大型互联网场景的线程池方案,建议使用ThreadPoolExecutor来指定线程池参数,这样可以明确线程池的运行规则,规避资源耗尽的风险。

  1. 定时器

定时器是一种控制任务延时调用,或者周期调用的技术。定时器的实现方式有两种:

方式一:Timer。创建Timer定时器对象,然后开启定时器。这是一种单线程方法,处理多个任务按照顺序执行,存在延时与设置定时器的时间有出入。可能因为其中的某个任务的异常使Timer线程死掉,从而影响后续任务执行。

    Timer t=new Timer();t.schedule(new TimerTask() {@Overridepublic void run() {System.out.println("定时器~");}},3000,3000);

方式二: ScheduledExecutorService定时器。基于线程池,某个任务的执行情况不会影响其他定时任务的执行。先得到线程池对象,然后再进行周期调度方法。

        ScheduledExecutorService pool=Executors.newScheduledThreadPool(3);pool.scheduleAtFixedRate(new TimerTask() {@Overridepublic void run() {System.out.println("定时器");}},3,3,TimeUnit.SECONDS);
  1. 并发与并行

CPU同时可以处理线程的数量有限,所以CPU会轮询为每个线程服务,只是由于CPU切换的速度很快,给我们的感觉这些线程在同时执行,其实可能只是并发。所以说多个线程其实是并发与并行同时进行的。

  1. 线程的6种状态

NEW(新建)

线程刚被创建,但是并未启动。

Runnable(可运行)

线程已经调用了start()等待CPU调度。

Blocked(锁阻塞)

线程在执行的时候未竞争到锁对象,则该线程进入Blocked状态。

Waiting(无限等待)

一个线程进入Waiting状态,另一个线程调用notify或者notifyAll方法才能够唤醒。

Timed Waiting(计时等待)

同waiting状态,有几个方法有超时参数,调用他们将进入Timed Waiting状态。带有超时参数的常用方法有Thread.sleep 、Object.wait。

Teminated(被终止)

因为run方法正常退出而死亡,或者因为没有捕获的异常终止了run方法而死亡。

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...