前些天由于用到多线程处理,所以想到线程池,搜集了网上的一些资料,再分析改进一下,有了下面的东西。
首先是个读取配置文件的类:
接着,是要做事的类,我写了一个接口,只有一个方法doWork(),在线程池中,一旦一个线程获得一个工作任务,线程就会调用工作任务的doWork()方法。
package
org.ofbiz.smsSend;

public
interface
Work
{
public abstract void doWork();
}
然后,就是主要的线程池类了:
首先是个读取配置文件的类:
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

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

接着,是要做事的类,我写了一个接口,只有一个方法doWork(),在线程池中,一旦一个线程获得一个工作任务,线程就会调用工作任务的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
定时器自动查失效的线程,用到的方法如下:

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

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
最后,配置文件的内容如下

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

1
#
----------------
线程池配置信息
-----------------
2
#
3
#线程池最小线程
4
minPools
=
10
5
#线程池最大线程
6
maxPools
=
100
7
#检查线程池中线程的周期(分钟)
8
checkThreadPeriod
=
5
ok,要用的时候,调用方法如下:

2

3

4

5

6

7

8

1
ThreadPool.getInstance().run(
new
(实现了work接口的类));
