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
















