前言
項(xiàng)目需要多線程執(zhí)行一些task,為了方便各個(gè)服務(wù)的使用。特意封裝了一個(gè)公共工具類(lèi),下面直接擼代碼:
poolconfig(線程池核心配置參數(shù)):
1
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
|
/** * <h1>線程池核心配置(<b style="color:#cd0000">基本線程池?cái)?shù)量、最大線程池?cái)?shù)量、隊(duì)列初始容量、線程連接保持活動(dòng)秒數(shù)(默認(rèn)60s)</b>)</h1> * * <blockquote><code> * <table border="1px" style="border-color:gray;" width="100%"><tbody> * <tr><th style="color:green;text-align:left;"> * 屬性名稱(chēng) * </th><th style="color:green;text-align:left;"> * 屬性含義 * </th></tr> * <tr><td> * queuecapacity * </td><td> * 基本線程池?cái)?shù)量 * </td></tr> * <tr><td> * count * </td><td> * 最大線程池?cái)?shù)量 * </td></tr> * <tr><td> * maxcount * </td><td> * 隊(duì)列初始容量 * </td></tr> * <tr><td> * alivesec * </td><td> * 線程連接保持活動(dòng)秒數(shù)(默認(rèn)60s) * </td></tr> * </tbody></table> * </code></blockquote> */ public class poolconfig { private int queuecapacity = 200 ; private int count = 0 ; private int maxcount = 0 ; private int alivesec; public int getqueuecapacity() { return queuecapacity; } public void setqueuecapacity( int queuecapacity) { this .queuecapacity = queuecapacity; } public void setcount( int count) { this .count = count; } public void setmaxcount( int maxcount) { this .maxcount = maxcount; } public void setalivesec( int alivesec) { this .alivesec = alivesec; } public int getcount() { return count; } public int getmaxcount() { return maxcount; } public int getalivesec() { return alivesec; } } |
threadpoolconfig(線程池配置 yml配置項(xiàng)以thread開(kāi)頭):
1
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
|
import java.util.arraylist; import java.util.hashmap; import java.util.list; import java.util.map; import org.springframework.boot.context.properties.configurationproperties; import org.springframework.stereotype.component; /** * <h1>線程池配置(<b style="color:#cd0000">線程池核心配置、各個(gè)業(yè)務(wù)處理的任務(wù)數(shù)量</b>)</h1> * * <blockquote><code> * <table border="1px" style="border-color:gray;" width="100%"><tbody> * <tr><th style="color:green;text-align:left;"> * 屬性名稱(chēng) * </th><th style="color:green;text-align:left;"> * 屬性含義 * </th></tr> * <tr><td> * pool * </td><td> * 線程池核心配置 * 【{@link poolconfig}】 * </td></tr> * <tr><td> * count * </td><td> * 線程池各個(gè)業(yè)務(wù)任務(wù)初始的任務(wù)數(shù) * </td></tr> * </tbody></table> * </code></blockquote> */ @component @configurationproperties (prefix= "thread" ) public class threadpoolconfig { private poolconfig pool = new poolconfig(); map<string, integer> count = new hashmap<>(); public poolconfig getpool() { return pool; } public void setpool(poolconfig pool) { this .pool = pool; } public map<string, integer> getcount() { return count; } } |
定義task注解,方便使用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
@target (elementtype.type) @retention (retentionpolicy.runtime) @documented @component public @interface excutortask { /** * the value may indicate a suggestion for a logical excutortask name, * to be turned into a spring bean in case of an autodetected excutortask . * @return the suggested excutortask name, if any */ string value() default "" ; } |
通過(guò)反射獲取使用task注解的任務(wù)集合:
1
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
|
public class beans { private static final char prefix = '.' ; public static concurrentmap<string, string> scanbeanclassnames(){ concurrentmap<string, string> beanclassnames = new concurrenthashmap<>(); classpathscanningcandidatecomponentprovider provider = new classpathscanningcandidatecomponentprovider( false ); provider.addincludefilter( new annotationtypefilter(excutortask. class )); for ( package pkg : package .getpackages()){ string basepackage = pkg.getname(); set<beandefinition> components = provider.findcandidatecomponents(basepackage); for (beandefinition component : components) { string beanclassname = component.getbeanclassname(); try { class <?> clazz = class .forname(component.getbeanclassname()); boolean isannotationpresent = clazz.isannotationpresent(zimatask. class ); if (isannotationpresent){ zimatask task = clazz.getannotation(excutortask. class ); string aliasname = task.value(); if (aliasname != null && ! "" .equals(aliasname)){ beanclassnames.put(aliasname, component.getbeanclassname()); } } } catch (classnotfoundexception e) { e.printstacktrace(); } beanclassnames.put(beanclassname.substring(beanclassname.lastindexof(prefix) + 1 ), component.getbeanclassname()); } } return beanclassnames; } } |
線程執(zhí)行類(lèi)taskpool:
1
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
|
@component public class taskpool { public threadpooltaskexecutor pooltaskexecutor; @autowired private threadpoolconfig threadpoolconfig; @autowired private applicationcontext context; private final integer max_pool_size = 2000 ; private poolconfig poolcfg; private map<string, integer> taskscount; private concurrentmap<string, string> beanclassnames; @postconstruct public void init() { beanclassnames = beans.scanbeanclassnames(); pooltaskexecutor = new threadpooltaskexecutor(); poolcfg = threadpoolconfig.getpool(); taskscount = threadpoolconfig.getcount(); int corepoolsize = poolcfg.getcount(), maxpoolsize = poolcfg.getmaxcount(), queuecapacity = poolcfg.getqueuecapacity(), minpoolsize = 0 , maxcount = (corepoolsize << 1 ); for (string taskname : taskscount.keyset()){ minpoolsize += taskscount.get(taskname); } if (corepoolsize > 0 ){ if (corepoolsize <= minpoolsize){ corepoolsize = minpoolsize; } } else { corepoolsize = minpoolsize; } if (queuecapacity > 0 ){ pooltaskexecutor.setqueuecapacity(queuecapacity); } if (corepoolsize > 0 ){ if (max_pool_size < corepoolsize){ corepoolsize = max_pool_size; } pooltaskexecutor.setcorepoolsize(corepoolsize); } if (maxpoolsize > 0 ){ if (maxpoolsize <= maxcount){ maxpoolsize = maxcount; } if (max_pool_size < maxpoolsize){ maxpoolsize = max_pool_size; } pooltaskexecutor.setmaxpoolsize(maxpoolsize); } if (poolcfg.getalivesec() > 0 ){ pooltaskexecutor.setkeepaliveseconds(poolcfg.getalivesec()); } pooltaskexecutor.initialize(); } public void execute( class <?>... clazz){ int i = 0 , len = taskscount.size(); for (; i < len; i++){ integer taskcount = taskscount.get(i); for ( int t = 0 ; t < taskcount; t++){ try { object taskobj = context.getbean(clazz[i]); if (taskobj != null ){ pooltaskexecutor.execute((runnable) taskobj); } } catch (exception ex){ ex.printstacktrace(); } } } } public void execute(string... args){ int i = 0 , len = taskscount.size(); for (; i < len; i++){ integer taskcount = taskscount.get(i); for ( int t = 0 ; t < taskcount; t++){ try { object taskobj = null ; if (context.containsbean(args[i])){ taskobj = context.getbean(args[i]); } else { if (beanclassnames.containskey(args[i].tolowercase())){ class <?> clazz = class .forname(beanclassnames.get(args[i].tolowercase())); taskobj = context.getbean(clazz); } } if (taskobj != null ){ pooltaskexecutor.execute((runnable) taskobj); } } catch (exception ex){ ex.printstacktrace(); } } } } public void execute(){ for (string taskname : taskscount.keyset()){ integer taskcount = taskscount.get(taskname); for ( int t = 0 ; t < taskcount; t++){ try { object taskobj = null ; if (context.containsbean(taskname)){ taskobj = context.getbean(taskname); } else { if (beanclassnames.containskey(taskname)){ class <?> clazz = class .forname(beanclassnames.get(taskname)); taskobj = context.getbean(clazz); } } if (taskobj != null ){ pooltaskexecutor.execute((runnable) taskobj); } } catch (exception ex){ ex.printstacktrace(); } } } } } |
如何使用?(做事就要做全套 ^_^)
1.因?yàn)槭褂玫膕pringboot項(xiàng)目,需要在application.properties 或者 application.yml 添加
1
2
3
4
5
|
#配置執(zhí)行的task線程數(shù) thread.count.needexcutortask= 4 #最大存活時(shí)間 thread.pool.alivesec= 300000 #其他配置同理 |
2.將我們寫(xiě)的線程配置進(jìn)行裝載到我們的項(xiàng)目中
1
2
3
4
5
6
7
8
9
10
11
|
@configuration public class taskmanager { @resource private taskpool taskpool; @postconstruct public void executor(){ taskpool.execute(); } } |
3.具體使用
1
2
3
4
5
6
7
8
|
@excutortask public class needexcutortask implements runnable{ @override public void run() { thread.sleep(1000l); log.info( "====== 任務(wù)執(zhí)行 =====" ) } } |
以上就是創(chuàng)建一個(gè)可擴(kuò)展的線程池相關(guān)的配置(望指教~~~)。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。
原文鏈接:https://blog.csdn.net/u011663149/article/details/86497456