zoukankan      html  css  js  c++  java
  • Java线程池实现原理之自定义线程池(一)

    1.队列的概念

    谈到多线程先讲下队列的概念,之后的多线程学习会用到此类知识。

    队列分为:阻塞式队列(有界)、非阻塞式队列(无界),遵循着先进先出、后进后出的原则。
    阻塞队列与非阻塞队列区别:
    1.非阻塞式队列超出队列总数会丢失。
    2.阻塞式队列超出总数会进入等待(等待时间=设置超时时间)。
    3.获取队列方面:非阻塞式队列,如果为空返回null。阻塞式队列,如果为空也会进入等待。

    非阻塞式队列ConcurrentLinkedDeque
    
    
     1 //非阻塞式队列 无界(可以声明无限个队列)
     2     public static void test1(){
     3 
     4         ConcurrentLinkedDeque<Object> objects = new ConcurrentLinkedDeque<>();
     5         objects.offer("java001");
     6         objects.offer("java002");
     7 
     8         System.out.println("队列总数:"+objects.size());
     9 
    10         //建议:获取队列之后删除
    11         System.out.println("获取队列但不删除:"+objects.peek());
    12         System.out.println("获取队列但不删除,队列总数:"+objects.size());
    13         System.out.println("获取队列删除:"+objects.poll());
    14 
    15         //非阻塞式队列,如果为空返回null
    16         System.out.println(objects.poll());
    17         System.out.println(objects.poll());
    18         System.out.println(objects.poll());
    19         System.out.println("获取队列删除,队列总数:"+objects.size());
    20     }
    
    
    
    
    
    阻塞式队列ArrayBlockingQueue
    
    
     1 //阻塞式队列
     2     public static void test2() throws InterruptedException {
     3 
     4         long startTime=System.currentTimeMillis();
     5         ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue<>(3);
     6         arrayBlockingQueue.offer("A001",3, TimeUnit.SECONDS);
     7         arrayBlockingQueue.offer("A002",3, TimeUnit.SECONDS);
     8 
     9         //阻塞式队列超出总数等待(等待时间=设置超时时间)
    10         arrayBlockingQueue.offer("A003",3, TimeUnit.SECONDS);
    11         arrayBlockingQueue.offer("A004",1, TimeUnit.SECONDS);
    12         arrayBlockingQueue.offer("A005",1, TimeUnit.SECONDS);
    13 
    14         System.out.println("队列总数:"+arrayBlockingQueue.size());
    15         System.out.println(arrayBlockingQueue.poll());
    16         System.out.println(arrayBlockingQueue.poll());
    17         System.out.println(arrayBlockingQueue.poll());
    18         //阻塞式队列,如果为空也会等待。
    19         System.out.println(arrayBlockingQueue.poll(1, TimeUnit.SECONDS));
    20         System.out.println("队列剩余总数:"+arrayBlockingQueue.size());
    21 
    22         System.out.println("耗时:"+ (System.currentTimeMillis() - startTime)/1000 +"秒");
    23 
    24     }
    
    

    2.线程池

    
    
    线程池好处:
    1.降低资源 => 重复利用机制 (降低创建线程和销毁线程)
    2.提高响应效率 => 当任务到达时,任务可以不需要等待去创建线程就可以执行
    3.方便管理 => 无限创建线程消耗资源、降低系统稳定性。使用线程池可以统一分配、调优、监控。
    线程与任务的区别:
    可以把线程理解成一个工作人员。而任务就是这个工作人员干的活。比如,餐厅的工作人员在为顾客传菜,传菜就是个任务。

    Java中线程就是Thread类或其子类的一个实例。
    也就是说你不必关注线程对象是用哪种方法创建的。在此基础上,线程所执行的代码,即run方法中的代码所实现的处理逻辑,
    比如读取数据库中的一条记录,就是一个任务。因此,所谓任务是一个相对的概念。一个任务可以是读取数据库中的一条记录,
    也可以是FTP传输一批文件,FTP传输一个文件……
    
    
     1 //创建线程四种方式:
     2     //1.可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
     3     //2.定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
     4     //3.可定时线程池,支持定时及周期性任务执行。
     5     //4.单例线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
     6     public static void test1() {
     7 
     8         //1.可缓存、定时、定长、单例
     9         ExecutorService executorService = Executors.newCachedThreadPool();
    10         for (int i = 0; i <10 ; i++) {
    11             final int i1 = i;
    12             executorService.execute(new Runnable() {
    13                 @Override
    14                 public void run() {
    15                     System.out.println(Thread.currentThread().getName()+",i:"+ i1);
    16                 }
    17             });
    18         }
    19 
    20     }
    21 
    22     public static void test2() {
    23 
    24         //2.可定长线程,核心线程5个,最多创建5个线程 (只会创建5个线程,其他线程共享这5个线程)
    25         ExecutorService executorService = Executors.newFixedThreadPool(5);
    26         for (int i = 0; i <10 ; i++) {
    27             final int i1 = i;
    28             executorService.execute(new Runnable() {
    29                 @Override
    30                 public void run() {
    31                     System.out.println(Thread.currentThread().getName()+",i:"+ i1);
    32                 }
    33             });
    34         }
    35     }
    36 
    37     public static void test3() {
    38 
    39         long l = System.currentTimeMillis();
    40         //3.可定时线程 =>核心线程数3 (延迟三秒执行)
    41         ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);
    42         for (int i = 0; i <10 ; i++) {
    43 
    44             final int i1 = i;
    45             scheduledExecutorService.schedule(new Runnable() {
    46                 @Override
    47                 public void run() {
    48                     System.out.println(Thread.currentThread().getName()+",i:"+ i1);
    49                     System.out.println("耗时:"+ (System.currentTimeMillis() -l)/1000 +"秒" );
    50                 }
    51             },3, TimeUnit.SECONDS);
    52         }
    53 
    54 
    55 
    56     }
    57 
    58     public static void test4() {
    59 
    60         //4.单例线程 =>核心线程数1 最大线程数1
    61         ExecutorService executorService = Executors.newSingleThreadExecutor();
    62         for (int i = 0; i <10 ; i++) {
    63             final int i1 = i;
    64             executorService.execute(new Runnable() {
    65                 @Override
    66                 public void run() {
    67                     System.out.println(Thread.currentThread().getName()+",i:"+ i1);
    68                 }
    69             });
    70         }
    71     }
    
    
    
     
  • 相关阅读:
    matlab在图像中画长方形(框)
    将matlab的figure保存为pdf,避免图片太大缺失
    机器学习经典书籍
    2008年北大核心有效期 计算机类核心(2011-01-31 15:02:46)
    解决Matlab画图直接保存.eps格式而导致图不全的问题
    matlab从文件夹名中获得该文件夹下所图像文件名
    获取图片中感兴趣区域的信息(Matlab实现)
    Eclipse 浏览(Navigate)菜单
    Eclipse 查找
    Eclipse 悬浮提示
  • 原文地址:https://www.cnblogs.com/IT-study/p/9045077.html
Copyright © 2011-2022 走看看