zoukankan      html  css  js  c++  java
  • java中线程池的实现【原创】

      前些天由于用到多线程处理,所以想到线程池,搜集了网上的一些资料,再分析改进一下,有了下面的东西。
      首先是个读取配置文件的类:

      1package org.ofbiz.smsSend;
      2import java.io.File;
      3import java.io.FileInputStream;
      4import java.io.FileNotFoundException;
      5import java.io.FileOutputStream;
      6import java.io.IOException;
      7import java.util.Properties;
      8
      9/**
     10 * @author zxub 2005-11-11 16:44:55
     11 */

     12
     13public class UtilProperties
     14{
     15
     16    //设置默认的配置文件路径
     17    private String fileName = System.getProperty("user.dir")
     18            + "/base/config.properties";
     19    private Properties prop;
     20    private FileInputStream in;
     21    private FileOutputStream out;
     22
     23    /**
     24     * 自定义配置文件路径
     25     * @param fileName
     26     */

     27    public UtilProperties(String filePath)
     28    {        
     29        this.fileName = System.getProperty("user.dir")+filePath;
     30        getFile();
     31    }

     32
     33    public UtilProperties()
     34    {
     35        getFile();
     36    }

     37    
     38    /**
     39     * 获取配置文件
     40     */

     41    private void getFile()
     42    {
     43        File file = new File(this.fileName);
     44        try
     45        {
     46            in = new FileInputStream(file);
     47            prop = new Properties();
     48            // 载入文件
     49            prop.load(in);
     50            in.close();
     51        }

     52        catch (FileNotFoundException e)
     53        {
     54            System.err.println("配置文件config.properties找不到!!");
     55        }

     56        catch (IOException e)
     57        {
     58            System.err.println("读取配置文件config.properties错误!!");
     59        }
            
     60    }

     61
     62    /**
     63     * 列出所有的配置文件内容
     64     */

     65    public void list()
     66    {
     67        prop.list(System.out);
     68    }

     69
     70    /**
     71     * 指定配置项名称,返回配置值
     72     * 
     73     * @param itemName
     74     *            String
     75     * @return String
     76     */

     77
     78    public String getValue(String itemName)
     79    {
     80
     81        return prop.getProperty(itemName);
     82
     83    }

     84
     85    /**
     86     * 设置配置项名称及其值
     87     * 
     88     * @param itemName
     89     *            String
     90     * @param value
     91     *            String
     92     */

     93
     94    public void setValue(String itemName, String value)
     95    {
     96        prop.setProperty(itemName, value);
     97    }

     98
     99    /**
    100     * 保存配置文件,指定文件名和抬头描述
    101     * 
    102     * @param fileName
    103     *            String
    104     * @param description
    105     *            String
    106     * @throws Exception
    107     */

    108    public void saveFile()
    109    {
    110        try
    111        {
    112            File f = new File(this.fileName);
    113            out = new FileOutputStream(f);
    114            prop.store(out, "");
    115            out.close();
    116        }

    117        catch (FileNotFoundException e)
    118        {
    119            e.printStackTrace();
    120        }

    121        catch (IOException e)
    122        {
    123            System.err.println("配置文件config.properties写入错误!!");
    124        }

    125
    126    }

    127
    128    /**
    129     * 删除一个属性
    130     * 
    131     * @param value
    132     *            String
    133     */

    134
    135    public void deleteValue(String value)
    136    {
    137        prop.remove(value);
    138    }

    139    
    140    public void changeFile(String filePath)
    141    {
    142        this.fileName = System.getProperty("user.dir")+filePath;
    143        getFile();
    144    }

    145
    146    
    147    public static void main(String[] args)
    148    {
    149        UtilProperties up = new UtilProperties();
    150        up.list();
    151        up.changeFile("/logs/config.properties");
    152        up.list();
    153        System.out.println("\n"+up.getValue("tmpSavePath"));
    154    }

    155
    156}

    157

      接着,是要做事的类,我写了一个接口,只有一个方法doWork(),在线程池中,一旦一个线程获得一个工作任务,线程就会调用工作任务的doWork()方法。
    package org.ofbiz.smsSend;

    public interface Work
    {
        
    public abstract void doWork();
    }

      然后,就是主要的线程池类了:
      1/**
      2 * @author zxub 2005-12-3 19:44:33
      3 */

      4package org.ofbiz.smsSend;
      5
      6import java.util.ArrayList;
      7import java.util.Iterator;
      8import java.util.LinkedList;
      9import java.util.Timer;
     10
     11public class ThreadPool
     12{    
     13    private static final UtilProperties utilProp = new UtilProperties();
     14    private static int minPools = Integer.parseInt(utilProp
     15        .getValue("minPools"));
     16    private static int maxPools = Integer.parseInt(utilProp
     17        .getValue("maxPools"));
     18    private static int checkThreadPeriod = Integer.parseInt(utilProp
     19        .getValue("checkThreadPeriod")) * 60 * 1000;
     20    private static ArrayList workThreadList; // 工作线程列表,保存所有的线程
     21    private static LinkedList taskList = null// 工作任务列表,保存将要执行的工作任务
     22    private static int totalThread = 0// 总线程数
     23    private static int freeThreadCount = 0// 未被使用的线程数目
     24    private java.util.Timer timer = null// 定时器
     25    private static Object o = new Object();
     26    
     27    private static ThreadPool pool=new ThreadPool();
     28    
     29    public static void setMinPools(int minPools)
     30    {
     31        ThreadPool.minPools = minPools;
     32    }

     33
     34    public static void setMaxPools(int maxPools)
     35    {
     36        ThreadPool.maxPools = maxPools;
     37    }

     38
     39    public static void setCheckThreadPeriod(int checkThreadPeriod)
     40    {
     41        ThreadPool.checkThreadPeriod = checkThreadPeriod;
     42    }

     43
     44    private ThreadPool()
     45    {        
     46        workThreadList = new ArrayList();
     47        taskList = new LinkedList();
     48        //初始化线程池
     49        for (int i = 0; i < ThreadPool.minPools; i++)
     50        {
     51            WorkerThread temp = new WorkerThread();
     52            totalThread = totalThread + 1;
     53            workThreadList.add(temp);
     54            temp.start();
     55            try
     56            {
     57                Thread.sleep(100);
     58            }

     59            catch (Exception e)
     60            {
     61            }

     62        }

     63        timer = new Timer(true); // 启动定时器
     64        timer.schedule(new CheckThreadTask(this), 0, checkThreadPeriod);
     65    }

     66    
     67    public static ThreadPool getInstance()
     68    {
     69        return pool;
     70    }

     71    
     72    public synchronized void run(Work work)
     73    {
     74        if (freeThreadCount == 0)
     75        {
     76            if (totalThread < maxPools)
     77            {
     78                WorkerThread temp = new WorkerThread();
     79                totalThread = totalThread + 1;
     80                workThreadList.add(temp);
     81                temp.start();
     82                synchronized (taskList)
     83                {
     84                    taskList.add(work);
     85                    taskList.notify();
     86                }

     87            }

     88            else
     89            {
     90                while (freeThreadCount == 0)
     91                {
     92                    try
     93                    {
     94                        Thread.sleep(200);
     95                    }

     96                    catch (InterruptedException e)
     97                    {
     98                    }

     99                }

    100                synchronized (taskList)
    101                {
    102                    taskList.add(work);
    103                    taskList.notify();
    104                }

    105            }

    106        }

    107        else
    108        {
    109            synchronized (taskList)
    110            {
    111                taskList.add(work);
    112                taskList.notify();
    113            }

    114        }

    115    }

    116
    117    /**
    118     * 检查工作线程列表,将非活动状态的线程换成活动状态的线程,保证线程池中的线程可用
    119     *
    120     */

    121    public synchronized void checkAllThreads()
    122    {
    123
    124        Iterator threadIterator = workThreadList.iterator();
    125
    126        while (threadIterator.hasNext())
    127        // 逐个遍厉
    128            WorkerThread workThread = (WorkerThread) threadIterator.next();
    129
    130            if (!(workThread.isAlive()))
    131            {
    132                // 如果处在非活动状态时
    133                workThread = new WorkerThread(); // 重新生成1个线程
    134                workThread.start(); // 启动
    135            }

    136        }

    137    }

    138
    139    public static void printInfo()
    140    {
    141        System.out.println("minPools:" + minPools);
    142        System.out.println("maxPools:" + maxPools);
    143        System.out.println("checkThreadPeriod:" + checkThreadPeriod);
    144        System.out.println("totalThread=" + totalThread);
    145        System.out.println("workThreadList.size()=" + workThreadList.size());
    146    }

    147   
    148    /**
    149     * 线程池中的工作线程类,由工作线程执行我们要进行的操作
    150     */

    151    class WorkerThread extends Thread
    152    {
    153        boolean running = true;
    154        Work work;
    155
    156        public void run()
    157        {
    158            while (running)
    159            {
    160                synchronized (o)
    161                {
    162                    freeThreadCount++//一进来说明多了一个可用线程
    163                }

    164                synchronized (taskList)
    165                {
    166                    while (taskList.size() == 0//当工作任务列表为空时,等待
    167                    {
    168                        try
    169                        {
    170                            taskList.wait();
    171                            if (!running) return;
    172                        }

    173                        catch (InterruptedException e)
    174                        {
    175                        }

    176                    }

    177                    synchronized (o)
    178                    {
    179                        freeThreadCount--//得到一个工作,可用线程要减1
    180                    }

    181                    work = (Work) taskList.removeLast(); //从任务列表处获得一个任务
    182                    if (work == nullreturn;
    183                }

    184                work.doWork();
    185            }

    186        }

    187    }

    188}

    189
      定时器自动查失效的线程,用到的方法如下:
     1package org.ofbiz.smsSend;
     2
     3import java.util.TimerTask;
     4
     5public class CheckThreadTask extends TimerTask
     6{
     7    private static boolean isRunning = false;
     8    private ThreadPool pool;
     9
    10    public CheckThreadTask(ThreadPool pool)
    11    {
    12        this.pool = pool;
    13    }

    14
    15    public void run()
    16    {
    17        if (!isRunning)
    18        {
    19            isRunning = true;
    20            pool.checkAllThreads();
    21            isRunning = false;
    22        }

    23    }

    24}

    25
      最后,配置文件的内容如下
    1#----------------线程池配置信息-----------------
    2#
    3#线程池最小线程
    4minPools=10
    5#线程池最大线程
    6maxPools=100
    7#检查线程池中线程的周期(分钟)
    8checkThreadPeriod=5
      ok,要用的时候,调用方法如下:
    1ThreadPool.getInstance().run(new (实现了work接口的类));
  • 相关阅读:
    我的Android学习路线(二)
    利用python3.x实现小爬虫下载贴吧内图片
    我的Android学习路线(一)
    根网科技面试题
    sql语句的执行顺序
    英文面试常见问题汇总
    关于oracle、sqlserver、mysql查询前N条数据的实现
    LinqToSql(一)
    关于一些概念的问题,命名空间,程序集,解决方案,项目
    索引器
  • 原文地址:https://www.cnblogs.com/zxub/p/293806.html
Copyright © 2011-2022 走看看