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

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 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
 */
  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
        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 == null) return;
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;
 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
#线程池最小线程
4
minPools=10
5
#线程池最大线程
6
maxPools=100
7
#检查线程池中线程的周期(分钟)
8
checkThreadPeriod=5  ok,要用的时候,调用方法如下:
1
ThreadPool.getInstance().run(new (实现了work接口的类));