当前位置:   article > 正文

JavaEE--线程池与定时器_线程池定时器

线程池定时器

一.线程池

1.线程池的简要介绍及其优点

为了解决频繁创建和销毁线程带来的巨大开销问题,我们引入了线程池。线程池,简单来说就是提前把线程创建好,放到用户态代码中写的数据结构里面,需要使用的时候从池子取,用完了再放回去。使用线程池避免了直接调用api创建和销毁线程这种需要内核完成的工作,整体上都是用户态代码,在很大程度上提高了效率。

2.线程池参数

corePoolSize:核心线程数 (线程池最少线程数)

maximumPoolSize:最大线程数 (线程池最大线程数)

keepAliveTime:非核心线程允许空闲的最大时间 (在该时间内没有任务执行,就被回收)   (非核心线程数+核心线程数=最大线程数)

unit:keepAliveTime参数的时间单位

workQueue:线程池的任务队列 (线程池提供submit方法,让其他线程把任务交给线程池,该队列把要执行的任务保存起来,以便后续线程池内部的工作线程消费这个队列,从而完成具体的任务执行)

threadFactory:线程工厂,把线程的属性提前初始化

handler:拒绝策略,总共分为四种

1)AbortPolicy:直接抛出异常

2)CallerRunsPolicy:谁负责添加任务,谁去负责执行任务

3)DiscardOldestPolicy:丢弃最老的任务,让新的任务去队列中派对

4)DiscardPolicy:丢弃最新的任务

3.线程池的创建

3.1 标准库中的线程池

1.标准库中提供了使用Executor创建线程池的几种方式:

(1) newFixedThreadPool:创建固定线程数目的线程池

(2) newCachedThreadPool:创建一个能够根据任务数目自动进行线程扩容的线程池

(3) newSingleThreadPoolExecutor:创建一个只包含单个线程的线程池

(4) newScheduledThreadPool:创建一个固定线程个数,但是任务延迟执行的线程池

3.2 简单实现线程池

一个线程池要包含的东西:1)有若干个线程  2)有任务队列  3)提供submit方法

  1. import java.util.concurrent.ArrayBlockingQueue;
  2. import java.util.concurrent.BlockingQueue;
  3. public class Thread_pool {
  4. private BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(1000);
  5. public Thread_pool(int n) {//初始化线程池,固定线程数
  6. for (int i = 0; i < n; i++) {
  7. Thread t = new Thread(() -> {
  8. while (true) {
  9. try {
  10. Runnable runnable = queue.take();
  11. runnable.run();
  12. } catch (InterruptedException e) {
  13. e.printStackTrace();
  14. }
  15. }
  16. });
  17. t.start();
  18. }
  19. }
  20. public void submit(Runnable runnable) throws InterruptedException {//把任务添加到线程中
  21. queue.put(runnable);
  22. }
  23. }

二.定时器 

1.定时器的简要介绍

定时器,简单来说就是一个“闹钟”,达到一个设定的时间之后,就执行指定好的代码

2.定时器的创建

2.1 标准库中的定时器

标准库中提供了Timer类用于创建定时器,Timer类的核心方法为schedule方法,该方法包含两个参数,第一个参数指定要执行的任务,第二个参数指定多长时间之后执行

  1. import java.util.Timer;
  2. import java.util.TimerTask;
  3. public class timer_test {
  4. public static void main(String[] args) {
  5. Timer timer=new Timer();
  6. timer.schedule(new TimerTask() {
  7. @Override
  8. public void run() {
  9. System.out.println("hello");
  10. }
  11. },2000);
  12. timer.schedule(new TimerTask() {//可以安排多个任务
  13. @Override
  14. public void run() {
  15. System.out.println("hello");
  16. }
  17. },3000);
  18. }
  19. }

2.2 简单实现定时器

一个定时器需要的东西:1) 定义一个类,表示一个任务 2) 通过一定的数据结构保存多个任务 3)有一个线程来负责执行任务

  1. import java.util.PriorityQueue;
  2. class MyTimerTask implements Comparable<MyTimerTask> {
  3. private Runnable runnable;
  4. private long time;
  5. public MyTimerTask(Runnable runnable, long delay) {
  6. this.runnable = runnable;
  7. this.time = System.currentTimeMillis() + delay;
  8. }
  9. public void run() {
  10. runnable.run();
  11. }
  12. public long getTime() {
  13. return time;
  14. }
  15. @Override
  16. public int compareTo(MyTimerTask o) {
  17. return (int) (this.time - o.time);
  18. }
  19. }
  20. public class MyTimer {
  21. private PriorityQueue<MyTimerTask> taskQueue = new PriorityQueue<>();
  22. private Object locker = new Object();
  23. public MyTimer() {
  24. //这个线程负责不停扫描上述队列的首元素来确定是否要执行任务
  25. Thread t = new Thread(() -> {
  26. try {
  27. while (true) {
  28. synchronized (locker) {
  29. if (taskQueue.size() == 0) {
  30. locker.wait();
  31. }
  32. MyTimerTask task = taskQueue.peek();
  33. long curTime = System.currentTimeMillis();
  34. if (curTime >= task.getTime()) {//时间到了要执行任务
  35. task.run();
  36. taskQueue.poll();
  37. } else {//时间没到
  38. locker.wait(task.getTime() - curTime);
  39. }
  40. }
  41. }
  42. } catch (InterruptedException e) {
  43. e.printStackTrace();
  44. }
  45. });
  46. t.start();
  47. }
  48. public void schedule(Runnable runnable, long delay) {
  49. synchronized (locker) {
  50. MyTimerTask task = new MyTimerTask(runnable, delay);
  51. taskQueue.offer(task);
  52. locker.notify();
  53. }
  54. }
  55. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/运维做开发/article/detail/897640
推荐阅读
相关标签
  

闽ICP备14008679号