zoukankan      html  css  js  c++  java
  • 实现JAVA线程池

    实现JAVA线程池

    线程池,只听过,没见过也没用过。项目中因为牵扯到图片下载,所以借此机会来学习一下这方面的知识。

      线程池的知识,我在这里就不进行总结了,网上是很多的,我这边文章主要就是总结一下自己写的线程池代码。

      首先先说一下我的思路。线程池嘛,肯定是一个对多个线程引用的一个对象,有添加任务、激活线程去完成任务、关闭等功能。工作线程需要保证完成一项任务之后不结束,那么需要run方法中是一个类似于死循环的循环,循环的出口是线程池关闭的标志。但是当线程池中没有任务时,工作线程不能让这个循环进去下去,这样实际上是增加的CPU负担,所以需要使工作线程在没有工作时处于等待状态(wait)。工作线程每次接收到任务时,就需要做指定的任务,因此需要一个任务接口,工作线程接收到任务则调用这个接口中的指定方法即可。

      

      线程池类

    复制代码
      1 package my.java.threadpool;
      2 
      3 import java.util.Collections;
      4 import java.util.LinkedList;
      5 import java.util.List;
      6 
      7 public class ThreadPool
      8 {
      9     private final int MAX_COUNT = 3;
     10     private WorkThread worker[] = new WorkThread[MAX_COUNT];
     11 
     12     private List<Task> taskList = Collections.synchronizedList(new LinkedList<Task>());
     13 
     14     private boolean isRun = false;
     15 
     16     private int length = 0;
     17     private boolean isShowLog;
     18 
     19     private static ThreadPool httpClient = new ThreadPool();
     20 
     21     private ThreadPool()
     22     {
     23         isRun = true;
     24         for (int i = 0; i < MAX_COUNT; i++)
     25         {
     26             worker[i] = new WorkThread(this, "工作线程" + i + "号");
     27 
     28             worker[i].start();
     29         }
     30     }
     31 
     32     public static ThreadPool getInstance()
     33     {
     34         return httpClient;
     35     }
     36 
     37     /**
     38      * 在线程池中添加新的任务
     39      * 
     40      * @param object
     41      *            操作线程可能需要的数据
     42      */
     43     public void addToThreadPool(Task run)
     44     {
     45         synchronized (taskList)
     46         {
     47             taskList.add(run);
     48             taskList.notify();
     49         }
     50     }
     51 
     52     public void closeTheadPool()
     53     {
     54         printLog("开始关闭线程池");
     55         isRun = false;
     56         synchronized (taskList)
     57         {
     58             taskList.clear();
     59 
     60             for (int i = 0; i < MAX_COUNT; i++)
     61             {
     62                 printLog("线程池关闭" + worker[i].getName());
     63                 worker[i].stopWorkThread();
     64             }
     65 
     66             taskList.notifyAll();
     67         }
     68     }
     69 
     70     public String getTaskLength()
     71     {
     72         return "已经运行" + length + "个任务";
     73     }
     74 
     75     public String getThreadPoolInfo()
     76     {
     77         StringBuffer sb = new StringBuffer();
     78         sb.append("线程池中共有" + MAX_COUNT + "个线程\n");
     79         for (int i = 0; i < MAX_COUNT; i++)
     80         {
     81             sb.append(worker[i].getName()).append("当前处于").append(worker[i].getState()).append("状态\n");
     82         }
     83         return sb.toString();
     84     }
     85 
     86     public Task getTask()
     87     {
     88         Task run = null;
     89         if (isRun)
     90         {
     91             synchronized (taskList)
     92             {
     93                 while (taskList.isEmpty())
     94                 {
     95                     try
     96                     {
     97                         printLog(Thread.currentThread().getName() + "暂停");
     98                         taskList.wait();
     99                     }
    100                     catch (InterruptedException e)
    101                     {
    102                         e.printStackTrace();
    103                     }
    104 
    105                     if (!isRun)
    106                         return null;
    107                 }
    108                 run = taskList.remove(0);
    109                 length++;
    110             }
    111         }
    112         return run;
    113     }
    114 
    115     public void printLog(String log)
    116     {
    117         if (isShowLog)
    118         {
    119             System.out.println(log);
    120         }
    121     }
    122 }
    复制代码

      工作线程类

    复制代码
     1 package my.java.threadpool;
     2 
     3 public class WorkThread extends Thread
     4 {
     5     private boolean isRun;
     6     private ThreadPool pool;
     7     private boolean isShowLog;
     8 
     9     public WorkThread(ThreadPool pool, String name)
    10     {
    11         isRun = true;
    12         this.pool = pool;
    13         setName(name);
    14     }
    15 
    16     @Override
    17     public void run()
    18     {
    19         printLog(getName() + "开启");
    20         while (isRun)
    21         {
    22             Task run = pool.getTask();
    23 
    24             if (null == run)
    25             {
    26                 continue;
    27             }
    28             printLog(getName() + "开始工作");
    29             try
    30             {
    31                 run.run();
    32             }
    33             catch (Exception e)
    34             {
    35                 e.printStackTrace();
    36             }
    37             printLog(getName() + "完成工作");
    38         }
    39 
    40         printLog(getName() + "关闭");
    41     }
    42 
    43     public void stopWorkThread()
    44     {
    45         isRun = false;
    46     }
    47     
    48     public void printLog(String log)
    49     {
    50         if (isShowLog)
    51         {
    52             System.out.println(log);
    53         }
    54     }
    55 }
    复制代码

      工作接口

    复制代码
    1 package my.java.threadpool;
    2 
    3 public interface Task
    4 {
    5     /**
    6      * 耗时操作,也就是工作线程具体要做的内容
    7      */
    8     public void run();
    9 }
    复制代码

      测试类

    复制代码
     1 package my.java.threadpool;
     2 
     3 import java.util.Random;
     4 
     5 public class Test
     6 {
     7     public static void main(String[] args) throws InterruptedException
     8     {
     9 
    10         ThreadPool pool = ThreadPool.getInstance();
    11 
    12         System.out.println("开始添加任务");
    13 
    14         for (int i = 0; i < 50; i++)
    15         {
    16             Task run = new Task()
    17             {
    18                 @Override
    19                 public void run()
    20                 {
    21                     try
    22                     {
    23                         Thread.sleep(new Random().nextInt(5) * 1000);
    24                     }
    25                     catch (InterruptedException e)
    26                     {
    27                         e.printStackTrace();
    28                     }
    29                 }
    30             };
    31             pool.addToThreadPool(run);
    32         }
    33 
    34         System.out.println(pool.getThreadPoolInfo());
    35         // Thread.sleep(100 * 1000);
    36         pool.closeTheadPool();
    37     }
    38 }
    复制代码
     
     
    分类: Android
  • 相关阅读:
    自定义注解!绝对是程序员装逼的利器!!
    mybatis连接数据库错误解决方法
    SQL基础
    【2021-1-5】QT+SQLsever数据库的数据管理系统
    以友盟+U-Push为例,深度解读消息推送的筛选架构解决方案应用与实践
    基于Linux的MySQL基本操作
    SQL server函数转Oracle问题之一,强行使用临时表
    安装 部署 postgresql数据库 搭建主从节点 (业务库)
    SQL练习题一(逐行累计)
    ThinkPHP中,display和assign用法详解
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3080578.html
Copyright © 2011-2022 走看看