java中线程池的实现【原创】

it2022-05-08  11

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

  1 package  org.ofbiz.smsSend;   2 import  java.io.File;   3 import  java.io.FileInputStream;   4 import  java.io.FileNotFoundException;   5 import  java.io.FileOutputStream;   6 import  java.io.IOException;   7 import  java.util.Properties;   8   9 /** */ /** 10 * @author zxub 2005-11-11 16:44:55 11 */  12  13 public   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 fileName103     *            String104     * @param description105     *            String106     * @throws Exception107     */108    public void saveFile()109    {110        try111        {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        }125126    }127128    /** *//**129     * 删除一个属性130     * 131     * @param value132     *            String133     */134135    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    }145146    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    }155156} 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 */   4 package  org.ofbiz.smsSend;   5   6 import  java.util.ArrayList;   7 import  java.util.Iterator;   8 import  java.util.LinkedList;   9 import  java.util.Timer;  10  11 public   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        else108        {109            synchronized (taskList)110            {111                taskList.add(work);112                taskList.notify();113            }114        }115    }116117    /** *//**118     * 检查工作线程列表,将非活动状态的线程换成活动状态的线程,保证线程池中的线程可用119     *120     */121    public synchronized void checkAllThreads()122    {123124        Iterator threadIterator = workThreadList.iterator();125126        while (threadIterator.hasNext())127        // 逐个遍厉128            WorkerThread workThread = (WorkerThread) threadIterator.next();129130            if (!(workThread.isAlive()))131            {132                // 如果处在非活动状态时133                workThread = new WorkerThread(); // 重新生成1个线程134                workThread.start(); // 启动135            }136        }137    }138139    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 Thread152    {153        boolean running = true;154        Work work;155156        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                        try169                        {170                            taskList.wait();171                            if (!running) return;172                        }173                        catch (InterruptedException e)174                        {175                        }176                    }177                    synchronized (o)178                    {179                        freeThreadCount--//得到一个工作,可用线程要减1180                    }181                    work = (Work) taskList.removeLast(); //从任务列表处获得一个任务182                    if (work == nullreturn;183                }184                work.doWork();185            }186        }187    }188} 189   定时器自动查失效的线程,用到的方法如下:  1 package  org.ofbiz.smsSend;  2  3 import  java.util.TimerTask;  4  5 public   class  CheckThreadTask  extends  TimerTask  6 { 7    private static boolean isRunning = false; 8    private ThreadPool pool; 910    public CheckThreadTask(ThreadPool pool)11    {12        this.pool = pool;13    }1415    public void run()16    {17        if (!isRunning)18        {19            isRunning = true;20            pool.checkAllThreads();21            isRunning = false;22        }23    }24} 25   最后,配置文件的内容如下 1 # ---------------- 线程池配置信息 ----------------- 2 # 3 #线程池最小线程 4 minPools = 10 5 #线程池最大线程 6 maxPools = 100 7 #检查线程池中线程的周期(分钟) 8 checkThreadPeriod = 5   ok,要用的时候,调用方法如下: 1 ThreadPool.getInstance().run( new  (实现了work接口的类));

转载于:https://www.cnblogs.com/zxub/archive/2005/12/09/293806.html


最新回复(0)