diff --git a/pom.xml b/pom.xml index 2cc4451cb..4083045f9 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ io.github.lunasaw luna-common luna-common - 2.5.3 + 2.5.4 common is project which contains common utils https://github.com/lunasaw/luna-common diff --git a/src/main/java/com/luna/common/constant/CharPoolConstant.java b/src/main/java/com/luna/common/constant/CharPoolConstant.java index 1fa9af00e..415e535e8 100644 --- a/src/main/java/com/luna/common/constant/CharPoolConstant.java +++ b/src/main/java/com/luna/common/constant/CharPoolConstant.java @@ -7,77 +7,108 @@ public interface CharPoolConstant { /** * 字符常量:空格符 {@code ' '} */ - char SPACE = ' '; + char SPACE = ' '; /** * 字符常量:制表符 {@code '\t'} */ - char TAB = ' '; + char TAB = ' '; /** * 字符常量:点 {@code '.'} */ - char DOT = '.'; + char DOT = '.'; /** * 字符常量:斜杠 {@code '/'} */ - char SLASH = '/'; + char SLASH = '/'; /** * 字符常量:反斜杠 {@code '\\'} */ - char BACKSLASH = '\\'; + char BACKSLASH = '\\'; /** * 字符常量:回车符 {@code '\r'} */ - char CR = '\r'; + char CR = '\r'; /** * 字符常量:换行符 {@code '\n'} */ - char LF = '\n'; + char LF = '\n'; /** * 字符常量:减号(连接符) {@code '-'} */ - char DASHED = '-'; + char DASHED = '-'; /** * 字符常量:下划线 {@code '_'} */ - char UNDERLINE = '_'; + char UNDERLINE = '_'; /** * 字符常量:逗号 {@code ','} */ - char COMMA = ','; + char COMMA = ','; /** * 字符常量:花括号(左) '{' */ - char DELIM_START = '{'; + char DELIM_START = '{'; /** * 字符常量:花括号(右) '}' */ - char DELIM_END = '}'; + char DELIM_END = '}'; /** * 字符常量:中括号(左) {@code '['} */ - char BRACKET_START = '['; + char BRACKET_START = '['; /** * 字符常量:中括号(右) {@code ']'} */ - char BRACKET_END = ']'; + char BRACKET_END = ']'; /** * 字符常量:双引号 {@code '"'} */ - char DOUBLE_QUOTES = '"'; + char DOUBLE_QUOTES = '"'; /** * 字符常量:单引号 {@code '\''} */ - char SINGLE_QUOTE = '\''; + char SINGLE_QUOTE = '\''; /** * 字符常量:与 {@code '&'} */ - char AMP = '&'; + char AMP = '&'; /** * 字符常量:冒号 {@code ':'} */ - char COLON = ':'; + char COLON = ':'; /** * 字符常量:艾特 {@code '@'} */ - char AT = '@'; + char AT = '@'; + + String EXCLUDE_CHAR = "♠♣♧♡♥❤❥❣♂♀✲☀☼☾☽◐◑☺☻☎☏✿❀№↑↓←→√×÷★℃℉°◆◇⊙■□△▽¿½☯✡㍿卍卐♂♀✚〓㎡♪♫♩♬㊚㊛囍㊒㊖Φ♀♂‖$@*&#※卍卐Ψ♫♬♭♩♪♯♮⌒¶∮‖€£¥$\n" + + "①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳⓪❶❷❸❹❺❻❼❽❾❿⓫⓬⓭⓮⓯⓰⓱⓲⓳⓴㊀㊁㊂㊃㊄㊅㊆㊇㊈㊉㈠㈡㈢㈣㈤㈥㈦㈧㈨㈩⑴⑵⑶⑷⑸⑹⑺⑻⑼⑽⑾⑿⒀⒁⒂⒃⒄⒅⒆⒇ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵\n" + + + "﹢﹣×÷±/=≌∽≦≧≒﹤﹥≈≡≠=≤≥<>≮≯∷∶∫∮∝∞∧∨∑∏∪∩∈∵∴⊥∥∠⌒⊙√∟⊿㏒㏑%‰⅟½⅓⅕⅙⅛⅔⅖⅚⅜¾⅗⅝⅞⅘≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≛≜≝≞≟≠≡≢≣≤≥≦≧≨≩⊰⊱⋛⋚∫∬∭∮∯∰∱∲∳%℅‰‱øØπ\n" + + "♥❣ღ♠♡♤❤❥♚ ♛ ♝ ♞ ♜ ♟ ♔ ♕ ♗ ♘ ♖ ♟°′″$¥〒¢£%@℃℉﹩﹪‰﹫㎡㏕㎜㎝㎞㏎³㎎㎏㏄º○¤%$º¹²³\n" + + "€£Ұ₴$₰¢₤¥₳₲₪₵₣₱฿¤₡₮₭₩₢₥₫₦zł﷼₠₧₯₨čर₹ƒ₸¢\n" + + "✐✎✏✑✒✍✉✁✂✃✄✆✉☎☏☑✓✔√☐☒✗✘ㄨ✕✖✖☢☠☣✈★☆✡囍㍿☯☰☲☱☴☵☶☳☷☜☞☝✍☚☛☟✌♤♧♡♢♠♣♥♦☀☁☂❄☃♨웃유❖☽☾☪✿♂♀✪✯☭➳卍卐√×■◆●○◐◑✙☺☻❀⚘♔♕♖♗♘♙♚♛♜♝♞♟♧♡♂\n" + + "♀♠♣♥❤☜☞☎☏⊙◎☺☻☼▧▨♨◐◑↔↕▪▒◊◦▣▤▥▦▩◘◈◇♬♪♩♭♪の★☆→あぃ£Ю〓§♤♥▶¤✲❈✿✲❈➹☀☂☁【】┱┲❣✚✪✣✤✥✦❉❥❦❧❃❂❁❀✄☪☣☢☠☭ღ▶▷◀◁☀☁☂☃☄★☆☇☈⊙☊☋☌☍ⓛⓞⓥⓔ╬\n" + + "『』∴☀♫♬♩♭♪☆∷﹌の★◎▶☺☻►◄▧▨♨◐◑↔↕↘▀▄█▌◦☼♪の☆→♧ぃ£❤▒▬♦◊◦♠♣▣۰•❤•۰►◄▧▨♨◐◑↔↕▪▫☼♦⊙●○①⊕◎Θ⊙¤㊣★☆♀◆◇◣◢◥▲▼△▽⊿◤◥✐✌✍✡✓✔✕✖♂♀♥♡☜☞☎☏⊙◎☺\n" + + "☻►◄▧▨♨◐◑↔↕♥♡▪▫☼♦▀▄█▌▐░▒▬♦◊◘◙◦☼♠♣▣▤▥▦▩◘◙◈♫♬♪♩♭♪✄☪☣☢☠♯♩♪♫♬♭♮☎☏☪♈ºº₪¤큐«»™♂✿♥ ◕‿-。 。◕‿◕。\n" + + "❤❥웃유♋☮✌☏☢☠✔☑♚▲♪✈✞÷↑↓◆◇⊙■□△▽¿─│♥❣♂♀☿Ⓐ✍✉☣☤✘☒♛▼♫⌘☪≈←→◈◎☉★☆⊿※¡━┃♡ღツ☼☁❅♒✎©®™Σ✪✯☭➳卐√↖↗●◐Θ◤◥︻〖〗┄┆℃℉°✿ϟ☃☂✄¢€£∞✫★½✡×↙↘\n" + + "○◑⊕◣◢︼【】┅┇☽☾✚〓▂▃▄▅▆▇█▉▊▋▌▍▎▏↔↕☽☾の•▸◂▴▾┈┊①②③④⑤⑥⑦⑧⑨⑩ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩ㍿▓♨♛❖♓☪✙┉┋☹☺☻تヅツッシÜϡﭢ™℠℗©®♥❤❥❣❦❧♡۵웃유ღ♋♂♀☿☼☀☁☂☄\n" + + "☾☽❄☃☈⊙☉℃℉❅✺ϟ☇♤♧♡♢♠♣♥♦☜☞☝✍☚☛☟✌✽✾✿❁❃❋❀⚘☑✓✔√☐☒✗✘ㄨ✕✖✖⋆✢✣✤✥❋✦✧✩✰✪✫✬✭✮✯❂✡★✱✲✳✴✵✶✷✸✹✺✻✼❄❅❆❇❈❉❊†☨✞✝☥☦☓☩☯☧☬☸✡♁✙♆。,、':∶;?‘’“”〝〞ˆˇ﹕︰﹔﹖﹑•¨….¸;!´?!~—ˉ|‖"〃`@﹫¡¿﹏﹋﹌︴﹟#﹩$﹠&﹪%*﹡﹢﹦﹤‐ ̄¯―﹨ˆ˜﹍﹎+=<__-\\ˇ~﹉﹊()〈〉‹›﹛﹜『』〖〗[]《》〔〕{}「」【】︵︷︿︹︽_﹁﹃︻︶︸﹀︺︾ˉ﹂﹄︼☩☨☦✞✛✜✝✙✠✚†‡◉○◌◍◎●◐◑◒◓◔◕◖◗❂☢⊗⊙◘◙◍⅟½⅓⅕⅙⅛⅔⅖⅚⅜¾⅗⅝⅞⅘≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≛≜≝≞≟≠≡≢≣≤≥≦≧≨≩⊰⊱⋛⋚∫∬∭∮∯∰∱∲∳%℅‰‱㊣㊎㊍㊌㊋㊏㊐㊊㊚㊛㊤㊥㊦㊧㊨㊒㊞㊑㊒\n" + + + "㊓㊔㊕㊖㊗㊘㊜㊝㊟㊠㊡㊢㊩㊪㊫㊬㊭㊮㊯㊰㊙㉿囍♔♕♖♗♘♙♚♛♜♝♞♟ℂℍℕℙℚℝℤℬℰℯℱℊℋℎℐℒℓℳℴ℘ℛℭ℮ℌℑℜℨ♪♫♩♬♭♮♯°øⒶ☮✌☪✡☭✯卐✐✎✏✑✒✍✉✁✂✃✄✆✉☎☏➟➡➢➣➤➥➦➧➨➚➘➙➛➜\n" + + "➝➞➸♐➲➳⏎➴➵➶➷➸➹➺➻➼➽←↑→↓↔↕↖↗↘↙↚↛↜↝↞↟↠↡↢↣↤↥↦↧↨➫➬➩➪➭➮➯➱↩↪↫↬↭↮↯↰↱↲↳↴↵↶↷↸↹↺↻↼↽↾↿⇀⇁⇂⇃⇄⇅⇆⇇⇈⇉⇊⇋⇌⇍⇎⇏⇐⇑⇒⇓⇔⇕⇖⇗⇘⇙⇚⇛⇜⇝⇞⇟⇠⇡⇢⇣⇤⇥⇦⇧⇨⇩⇪➀➁➂➃➄\n" + + "➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓㊀㊁㊂㊃㊄㊅㊆㊇㊈㊉ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟\n" + + "┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋╌╍╎╏═║╒╓╔╕╖╗╘╙╚╛╜╝╞╟╠╡╢╣╤╥╦╧╨╩╪╫╬◤◥◄►▶◀◣◢▲▼◥▸◂▴▾△▽▷◁⊿▻◅▵▿▹◃❏❐❑❒▀▁▂▃▄▅▆\n" + + "▇▉▊▋█▌▍▎▏▐░▒▓▔▕■□▢▣▤▥▦▧▨▩▪▫▬▭▮▯㋀㋁㋂㋃㋄㋅㋆㋇㋈㋉㋊㋋㏠㏡㏢㏣㏤㏥㏦㏧㏨㏩㏪㏫㏬㏭㏮㏯㏰㏱㏲㏳㏴㏵㏶㏷㏸㏹㏺㏻㏼㏽㏾㍙㍚㍛㍜㍝㍞㍟㍠㍡㍢㍣㍤㍥㍦㍧㍨㍩㍪㍫㍬㍭㍮㍯㍰㍘☰☲☱☴\n" + + "☵☶☳☷☯\n" + + "。,、':∶;?‘’“”〝〞ˆˇ﹕︰﹔﹖﹑•¨….¸;!´?!~—ˉ|‖"〃`@﹫¡¿﹏﹋﹌︴々﹟#﹩$﹠&﹪%*﹡﹢﹦﹤‐ ̄¯―﹨ˆ˜﹍﹎+=<__-\\ˇ~﹉﹊()〈〉‹›﹛﹜『』〖〗[]《》〔〕{}「」【】︵︷︿︹︽_﹁﹃︻︶︸﹀︺︾ˉ﹂﹄︼❝❞\n" + + "↑↓←→↖↗↘↙↔↕➻➼➽➸➳➺➻➴➵➶➷➹▶►▷◁◀◄«»➩➪➫➬➭➮➯➱⏎➲➾➔➘➙➚➛➜➝➞➟➠➡➢➣➤➥➦➧➨↚↛↜↝↞↟↠↠↡↢↣↤↤↥↦↧↨⇄⇅⇆⇇⇈⇉⇊⇋⇌⇍⇎⇏⇐⇑⇒⇓⇔⇖⇗⇘⇙⇜↩↪↫↬↭↮↯↰↱↲↳↴↵↶↷↸↹☇☈↼↽↾↿⇀⇁⇂⇃⇞⇟⇠⇡⇢⇣⇤⇥⇦⇧⇨⇩⇪↺↻⇚⇛♐\n" + + + "─ ━│┃╌╍╎╏┄ ┅┆┇┈ ┉┊┋┌┍┎┏┐┑┒┓└ ┕┖┗ ┘┙┚┛├┝┞┟┠┡┢┣ ┤┥┦┧┨┩┪┫┬ ┭ ┮ ┯ ┰ ┱ ┲ ┳ ┴ ┵ ┶ ┷ ┸ ┹ ┺ ┻┼ ┽ ┾ ┿ ╀ ╁ ╂ ╃ ╄ ╅ ╆ ╇ ╈ ╉ ╊ ╋ ╪ ╫ ╬═║╒╓╔ ╕╖╗╘╙╚ ╛╜╝╞╟╠ ╡╢╣╤ ╥ ╦ ╧ ╨ ╩ ╳╔ ╗╝╚ ╬ ═ ╓ ╩ ┠ ┨┯ ┷┏ ┓┗ ┛┳ ⊥ ﹃ ﹄┌ ╮ ╭ ╯╰\n" + + + "ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろゎわゐゑをんゔゕゖァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶヷヸヹヺ・ーヽヾヿ゠ㇰㇱㇲㇳㇴㇵㇶㇷㇸㇹㇺㇻㇼㇽㇾㇿ\n" + + + "āáǎàōóǒòēéěèīíǐìūúǔùǖǘǚǜüêɑ\uE7C7ńň\uE7C8ɡㄅㄆㄇㄈㄉㄊㄋㄌㄍㄎㄏㄐㄑㄒㄓㄔㄕㄖㄗㄘㄙㄚㄛㄜㄝㄞㄟㄠㄡㄢㄣㄤㄥㄦㄧㄨㄩ\n" + + "БГДЁЖИЙКЛПФЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя|()`"; + } diff --git a/src/main/java/com/luna/common/math/MathConvertUtil.java b/src/main/java/com/luna/common/math/MathConvertUtil.java new file mode 100644 index 000000000..c0c7b500a --- /dev/null +++ b/src/main/java/com/luna/common/math/MathConvertUtil.java @@ -0,0 +1,127 @@ +package com.luna.common.math; + +import java.math.BigDecimal; +import java.math.RoundingMode; + +import org.apache.commons.lang3.StringUtils; + +public class MathConvertUtil { + + public static boolean asBoolean(Object obj, boolean defaultBoolean) { + if (obj == null) + return defaultBoolean; + try { + return Boolean.getBoolean(obj.toString()); + } catch (Exception ex) { + return defaultBoolean; + } + } + + public static int asInt(String entryStr) { + if (StringUtils.isEmpty(entryStr)) { + return 0; + } + try { + return Integer.parseInt(entryStr); + } catch (Exception ex) { + return 0; + } + } + + public static Integer asInteger(String entryStr) { + if (StringUtils.isEmpty(entryStr)) { + return null; + } + try { + return Integer.parseInt(entryStr); + } catch (Exception ex) { + return null; + } + } + + public static long asLong(String entryStr) { + if (StringUtils.isEmpty(entryStr)) { + return 0L; + } + try { + return Long.parseLong(entryStr); + } catch (Exception ex) { + return 0L; + } + } + + /** + * 这里保留2未精度 + * 入参500,出参5 + * + * @param entryStr + * @return + */ + public static double longConvert2Double(long entryStr) { + try { + return BigDecimal.valueOf(entryStr).divide( + BigDecimal.valueOf(100), 2, + RoundingMode.HALF_UP).doubleValue(); + } catch (Exception ex) { + return 0L; + } + } + + /** + * 转换成精确到2位精度 + * + * @param entryStr + * @return + */ + public static long doubleConvert2Long(double entryStr) { + try { + return BigDecimal.valueOf(entryStr).multiply( + BigDecimal.valueOf(100)).longValue(); + } catch (Exception ex) { + return 0L; + } + } + + public static boolean asBoolean(String entryStr) { + try { + return Boolean.parseBoolean(entryStr); + } catch (Exception ex) { + return false; + } + } + + public static Boolean asBooleanObject(String entryStr) { + if (StringUtils.isEmpty(entryStr)) { + return null; + } + try { + return Boolean.parseBoolean(entryStr); + } catch (Exception ex) { + return false; + } + } + + public static String asString(Object entryStr) { + if (null == entryStr) + return ""; + return entryStr.toString(); + } + + public static boolean isBlank(final CharSequence cs) { + int strLen; + if (cs == null || (strLen = cs.length()) == 0) { + return true; + } + for (int i = 0; i < strLen; i++) { + if (!Character.isWhitespace(cs.charAt(i))) { + return false; + } + } + return true; + } + + public static void main(String[] args) { + + } + +} diff --git a/src/main/java/com/luna/common/os/Profiler.java b/src/main/java/com/luna/common/os/Profiler.java new file mode 100644 index 000000000..11b3df62f --- /dev/null +++ b/src/main/java/com/luna/common/os/Profiler.java @@ -0,0 +1,512 @@ +package com.luna.common.os; + + +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * 用来测试并统计线程执行时间的工具。 + * + */ +public final class Profiler { + private static final ThreadLocal entryStack = new ThreadLocal(); + + /** + * 开始计时。 + */ + public static void start() { + start((String) null); + } + + /** + * 开始计时。 + * + * @param message 第一个entry的信息 + */ + public static void start(String message) { + entryStack.set(new Entry(message, null, null)); + } + + /** + * 开始计时。 + * + * @param message 第一个entry的信息 + */ + public static void start(Message message) { + entryStack.set(new Entry(message, null, null)); + } + + /** + * 清除计时器。 + * + *

+ * 清除以后必须再次调用start方可重新计时。 + *

+ */ + public static void reset() { + entryStack.set(null); + } + + /** + * 开始一个新的entry,并计时。 + * + * @param message 新entry的信息 + */ + public static void enter(String message) { + Entry currentEntry = getCurrentEntry(); + + if (currentEntry != null) { + currentEntry.enterSubEntry(message); + } + } + + /** + * 开始一个新的entry,并计时。 + * + * @param message 新entry的信息 + */ + public static void enter(Message message) { + Entry currentEntry = getCurrentEntry(); + + if (currentEntry != null) { + currentEntry.enterSubEntry(message); + } + } + + /** + * 结束最近的一个entry,记录结束时间。 + */ + public static void release() { + Entry currentEntry = getCurrentEntry(); + + if (currentEntry != null) { + currentEntry.release(); + } + } + + /** + * 取得耗费的总时间。 + * + * @return 耗费的总时间,如果未开始计时,则返回-1 + */ + public static long getDuration() { + Entry entry = (Entry) entryStack.get(); + + if (entry != null) { + return entry.getDuration(); + } else { + return -1; + } + } + + /** + * 列出所有的entry。 + * + * @return 列出所有entry,并统计各自所占用的时间 + */ + public static String dump() { + return dump("", ""); + } + + /** + * 列出所有的entry。 + * + * @param prefix 前缀 + * + * @return 列出所有entry,并统计各自所占用的时间 + */ + public static String dump(String prefix) { + return dump(prefix, prefix); + } + + /** + * 列出所有的entry。 + * + * @param prefix1 首行前缀 + * @param prefix2 后续行前缀 + * + * @return 列出所有entry,并统计各自所占用的时间 + */ + public static String dump(String prefix1, String prefix2) { + Entry entry = (Entry) entryStack.get(); + + if (entry != null) { + return entry.toString(prefix1, prefix2); + } else { + return ""; + } + } + + /** + * 取得第一个entry。 + * + * @return 第一个entry,如果不存在,则返回null + */ + public static Entry getEntry() { + return (Entry) entryStack.get(); + } + + /** + * 取得最近的一个entry。 + * + * @return 最近的一个entry,如果不存在,则返回null + */ + private static Entry getCurrentEntry() { + Entry subEntry = (Entry) entryStack.get(); + Entry entry = null; + + if (subEntry != null) { + do { + entry = subEntry; + subEntry = entry.getUnreleasedEntry(); + } while (subEntry != null); + } + + return entry; + } + + /** + * 代表一个计时单元。 + */ + public static final class Entry { + private final List subEntries = new ArrayList(4); + private final Object message; + private final Entry parentEntry; + private final Entry firstEntry; + private final long baseTime; + private final long startTime; + private long endTime; + + /** + * 创建一个新的entry。 + * + * @param message entry的信息,可以是null + * @param parentEntry 父entry,可以是null + * @param firstEntry 第一个entry,可以是null + */ + private Entry(Object message, Entry parentEntry, Entry firstEntry) { + this.message = message; + this.startTime = System.currentTimeMillis(); + this.parentEntry = parentEntry; + this.firstEntry = (Entry) defaultIfNull(firstEntry, this); + this.baseTime = (firstEntry == null) ? 0 + : firstEntry.startTime; + } + + public static Object defaultIfNull(Object object, Object defaultValue) { + return (object != null) ? object + : defaultValue; + } + + /** + * 取得entry的信息。 + */ + public String getMessage() { + String messageString = null; + + if (message instanceof String) { + messageString = (String) message; + } else if (message instanceof Message) { + Message messageObject = (Message) message; + MessageLevel level = MessageLevel.BRIEF_MESSAGE; + + if (isReleased()) { + level = messageObject.getMessageLevel(this); + } + + if (level == MessageLevel.DETAILED_MESSAGE) { + messageString = messageObject.getDetailedMessage(); + } else { + messageString = messageObject.getBriefMessage(); + } + } + + return defaultIfEmpty(messageString, null); + } + + private static String defaultIfEmpty(String str, String defaultStr) { + return ((str == null) || (str.length() == 0)) ? defaultStr + : str; + } + + /** + * 取得entry相对于第一个entry的起始时间。 + * + * @return 相对起始时间 + */ + public long getStartTime() { + return (baseTime > 0) ? (startTime - baseTime) + : 0; + } + + /** + * 取得entry相对于第一个entry的结束时间。 + * + * @return 相对结束时间,如果entry还未结束,则返回-1 + */ + public long getEndTime() { + if (endTime < baseTime) { + return -1; + } else { + return endTime - baseTime; + } + } + + /** + * 取得entry持续的时间。 + * + * @return entry持续的时间,如果entry还未结束,则返回-1 + */ + public long getDuration() { + if (endTime < startTime) { + return -1; + } else { + return endTime - startTime; + } + } + + /** + * 取得entry自身所用的时间,即总时间减去所有子entry所用的时间。 + * + * @return entry自身所用的时间,如果entry还未结束,则返回-1 + */ + public long getDurationOfSelf() { + long duration = getDuration(); + + if (duration < 0) { + return -1; + } else if (subEntries.isEmpty()) { + return duration; + } else { + for (int i = 0; i < subEntries.size(); i++) { + Entry subEntry = (Entry) subEntries.get(i); + + duration -= subEntry.getDuration(); + } + + if (duration < 0) { + return -1; + } else { + return duration; + } + } + } + + /** + * 取得当前entry在父entry中所占的时间百分比。 + * + * @return 百分比 + */ + public double getPecentage() { + double parentDuration = 0; + double duration = getDuration(); + + if ((parentEntry != null) && parentEntry.isReleased()) { + parentDuration = parentEntry.getDuration(); + } + + if ((duration > 0) && (parentDuration > 0)) { + return duration / parentDuration; + } else { + return 0; + } + } + + /** + * 取得当前entry在第一个entry中所占的时间百分比。 + * + * @return 百分比 + */ + public double getPecentageOfAll() { + double firstDuration = 0; + double duration = getDuration(); + + if ((firstEntry != null) && firstEntry.isReleased()) { + firstDuration = firstEntry.getDuration(); + } + + if ((duration > 0) && (firstDuration > 0)) { + return duration / firstDuration; + } else { + return 0; + } + } + + /** + * 取得所有子entries。 + * + * @return 所有子entries的列表(不可更改) + */ + public List getSubEntries() { + return Collections.unmodifiableList(subEntries); + } + + /** + * 结束当前entry,并记录结束时间。 + */ + private void release() { + endTime = System.currentTimeMillis(); + } + + /** + * 判断当前entry是否结束。 + * + * @return 如果entry已经结束,则返回true + */ + private boolean isReleased() { + return endTime > 0; + } + + /** + * 创建一个新的子entry。 + * + * @param message 子entry的信息 + */ + private void enterSubEntry(Object message) { + Entry subEntry = new Entry(message, this, firstEntry); + + subEntries.add(subEntry); + } + + /** + * 取得未结束的子entry。 + * + * @return 未结束的子entry,如果没有子entry,或所有entry均已结束,则返回null + */ + private Entry getUnreleasedEntry() { + Entry subEntry = null; + + if (!subEntries.isEmpty()) { + subEntry = (Entry) subEntries.get(subEntries.size() - 1); + + if (subEntry.isReleased()) { + subEntry = null; + } + } + + return subEntry; + } + + /** + * 将entry转换成字符串的表示。 + * + * @return 字符串表示的entry + */ + public String toString() { + return toString("", ""); + } + + /** + * 将entry转换成字符串的表示。 + * + * @param prefix1 首行前缀 + * @param prefix2 后续行前缀 + * + * @return 字符串表示的entry + */ + private String toString(String prefix1, String prefix2) { + StringBuffer buffer = new StringBuffer(); + + toString(buffer, prefix1, prefix2); + + return buffer.toString(); + } + + /** + * 将entry转换成字符串的表示。 + * + * @param buffer 字符串buffer + * @param prefix1 首行前缀 + * @param prefix2 后续行前缀 + */ + private void toString(StringBuffer buffer, String prefix1, String prefix2) { + buffer.append(prefix1); + + String message = getMessage(); + long startTime = getStartTime(); + long duration = getDuration(); + long durationOfSelf = getDurationOfSelf(); + double percent = getPecentage(); + double percentOfAll = getPecentageOfAll(); + + Object[] params = new Object[] { + message, // {0} - entry信息 + new Long(startTime), // {1} - 起始时间 + new Long(duration), // {2} - 持续总时间 + new Long(durationOfSelf), // {3} - 自身消耗的时间 + new Double(percent), // {4} - 在父entry中所占的时间比例 + new Double(percentOfAll) // {5} - 在总时间中所旧的时间比例 + }; + + StringBuffer pattern = new StringBuffer("{1,number} "); + + if (isReleased()) { + pattern.append("[{2,number}ms"); + + if ((durationOfSelf > 0) && (durationOfSelf != duration)) { + pattern.append(" ({3,number}ms)"); + } + + if (percent > 0) { + pattern.append(", {4,number,##%}"); + } + + if (percentOfAll > 0) { + pattern.append(", {5,number,##%}"); + } + + pattern.append("]"); + } else { + pattern.append("[UNRELEASED]"); + } + + if (message != null) { + pattern.append(" - {0}"); + } + + buffer.append(MessageFormat.format(pattern.toString(), params)); + + for (int i = 0; i < subEntries.size(); i++) { + Entry subEntry = (Entry) subEntries.get(i); + + buffer.append('\n'); + + if (i == (subEntries.size() - 1)) { + subEntry.toString(buffer, prefix2 + "`---", prefix2 + " "); // 最后一项 + } else if (i == 0) { + subEntry.toString(buffer, prefix2 + "+---", prefix2 + "| "); // 第一项 + } else { + subEntry.toString(buffer, prefix2 + "+---", prefix2 + "| "); // 中间项 + } + } + } + } + + /** + * 显示消息的级别。 + */ +// public static final class MessageLevel extends IntegerEnum { +// private static final long serialVersionUID = 3257849896026388537L; +// public static final MessageLevel NO_MESSAGE = (MessageLevel) create(); +// public static final MessageLevel BRIEF_MESSAGE = (MessageLevel) create(); +// public static final MessageLevel DETAILED_MESSAGE = (MessageLevel) create(); +// } + + public enum MessageLevel + { + NO_MESSAGE,BRIEF_MESSAGE,DETAILED_MESSAGE; + } + + /** + * 代表一个profiler entry的详细信息。 + */ + public interface Message { + MessageLevel getMessageLevel(Entry entry); + + String getBriefMessage(); + + String getDetailedMessage(); + } +} diff --git a/src/main/java/com/luna/common/text/DataDesensitizationUtils.java b/src/main/java/com/luna/common/sensitive/DataDesensitizationUtils.java similarity index 94% rename from src/main/java/com/luna/common/text/DataDesensitizationUtils.java rename to src/main/java/com/luna/common/sensitive/DataDesensitizationUtils.java index 40cca2f96..bca7ef12e 100644 --- a/src/main/java/com/luna/common/text/DataDesensitizationUtils.java +++ b/src/main/java/com/luna/common/sensitive/DataDesensitizationUtils.java @@ -1,4 +1,6 @@ -package com.luna.common.text; +package com.luna.common.sensitive; + +import com.luna.common.text.StringTools; /** * @author luna diff --git a/src/main/java/com/luna/common/text/FeatureUtils.java b/src/main/java/com/luna/common/text/FeatureUtils.java new file mode 100644 index 000000000..8b9e47148 --- /dev/null +++ b/src/main/java/com/luna/common/text/FeatureUtils.java @@ -0,0 +1,302 @@ +package com.luna.common.text; + +import java.util.*; +import java.util.stream.Collectors; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + +import com.google.common.collect.Lists; +import com.luna.common.constant.StrPoolConstant; + +/** + * Created by weidian2015090105 on 15/9/27. + */ +public class FeatureUtils { + + public static final String FEATURE_SEPERATOR = ";"; + public static final String KEY_VALUE_SEPERATOR = ":"; + + /** + * 设置一个feature。如果已经存在,则替换;如果不存在,则添加。origFeatures可以为空,直接返回aKey:aValue。 + * + * @param origFeatures 原始的features字段。可以为空。 + * @param aKey 需要设置的feature的key + * @param aValue 需要设置的feature的value + * @return 返回添加或修改后的整个features字段 + */ + public static String addOrUpdateAFeature(String origFeatures, String aKey, String aValue) { + + if (null == aKey || aKey.trim().isEmpty()) { + return origFeatures; + } + + if (null == aValue || aValue.trim().isEmpty()) { + return origFeatures; + } + + if (origFeatures == null || origFeatures.isEmpty()) { + return aKey + KEY_VALUE_SEPERATOR + aValue; + } + + List featureList = convertToList(origFeatures); + for (Iterator itor = featureList.iterator(); itor.hasNext();) { + String[] sa = itor.next(); + if (aKey.equals(sa[0])) { + sa[1] = aValue; + return convertFromCollection(featureList); + } + } + + featureList.add(new String[] {aKey, aValue}); + return convertFromCollection(featureList); + + } + + /** + * 删除一个feature。 + * + * @param origFeatures 原始features。 + * @param aKey 待删除的feature的key。 + * @return 返回删除后的features + */ + public static String removeAFeature(String origFeatures, + String aKey) { + + if (StringUtils.isBlank(origFeatures) || StringUtils.isBlank(aKey)) { + return origFeatures; + } + + List featureList = convertToList(origFeatures); + for (Iterator itor = featureList.iterator(); itor.hasNext();) { + String[] sa = itor.next(); + if (aKey.equals(sa[0])) { + itor.remove(); + return convertFromCollection(featureList); + } + } + + return origFeatures; + + } + + /** + * 从featureStr中获得指定key的value。如果需要获得一个字符串中的多个feature,建议使用convertToMap()方法。不要重复调用getAFeature。 + * + * @param featureStr + * @param key + * @return + */ + public static String getAFeature(String featureStr, String key) { + if (StringUtils.isBlank(featureStr)) { + return null; + } + + StringTokenizer st = new StringTokenizer(featureStr, FEATURE_SEPERATOR); + + while (st.hasMoreTokens()) { + String kv = st.nextToken(); + + int kvSeperatorIndex = kv.indexOf(KEY_VALUE_SEPERATOR); // index of the key-value seperator. + + if (kvSeperatorIndex > 0) { + String k = kv.substring(0, kvSeperatorIndex); + if (k.equals(key)) { + String value = null; + if (kvSeperatorIndex + 1 < kv.length()) { // deal IndexOutOfBound + value = kv.substring(kvSeperatorIndex + 1); + } else { + value = ""; + } + return value; + } + } + } + + return null; + } + + /** + * 从featureStr中获得指定key的Long型value,注意有可能抛出NumberFormatException + * + * @param featureStr + * @param key + * @return + */ + public static Long getAFeatureLong(String featureStr, String key) { + String value = getAFeature(featureStr, key); + if (StringUtils.isBlank(value)) { + return null; + } + + return Long.valueOf(value); + } + + /** + * 获得所有feature的Map。 + * 如果feature为空,返回空的Map。 + * + * @return + */ + public static Map convertToMap(String featureStr) { + if (StringUtils.isBlank(featureStr)) { + return new HashMap(); + } + + Map featureMap = new HashMap(); + StringTokenizer st = new StringTokenizer(featureStr, FEATURE_SEPERATOR); + + while (st.hasMoreTokens()) { + String kv = st.nextToken(); + + int kvSeperatorIndex = kv.indexOf(KEY_VALUE_SEPERATOR); // index of the key-value seperator. + + if (kvSeperatorIndex > 0) { + String key = kv.substring(0, kvSeperatorIndex); + String value = null; + if (kvSeperatorIndex + 1 < kv.length()) { // deal IndexOutOfBound + value = kv.substring(kvSeperatorIndex + 1); + } else { + value = ""; + } + featureMap.put(key, value); + } + } + + return featureMap; + + } + + public static Map convertToMap(String featureStr, String seperator) { + if (StringUtils.isBlank(featureStr)) { + return new HashMap(); + } + + Map featureMap = new HashMap(); + StringTokenizer st = new StringTokenizer(featureStr, seperator); + + while (st.hasMoreTokens()) { + String kv = st.nextToken(); + + int kvSeperatorIndex = kv.indexOf(KEY_VALUE_SEPERATOR); // index of the key-value seperator. + + if (kvSeperatorIndex > 0) { + String key = kv.substring(0, kvSeperatorIndex); + String value = null; + if (kvSeperatorIndex + 1 < kv.length()) { // deal IndexOutOfBound + value = kv.substring(kvSeperatorIndex + 1); + } else { + value = ""; + } + featureMap.put(key, value); + } + } + + return featureMap; + + } + + public static String convertFromMap(Map featureMap) { + if (featureMap == null) + return null; + if (featureMap.size() == 0) + return ""; + + StringBuilder sb = new StringBuilder(); + boolean first = true; + for (Map.Entry e : featureMap.entrySet()) { + if (!first) { + sb.append(FEATURE_SEPERATOR); + } else { + first = false; + } + sb.append(e.getKey()).append(KEY_VALUE_SEPERATOR).append(e.getValue()); + } + + return sb.toString(); + } + + public static String convertFromCollection(Collection featureCollection) { + if (featureCollection == null) + return null; + if (featureCollection.size() == 0) + return ""; + + StringBuilder sb = new StringBuilder(); + boolean first = true; + for (String[] sa : featureCollection) { + if (!first) { + sb.append(FEATURE_SEPERATOR); + } else { + first = false; + } + sb.append(sa[0]).append(KEY_VALUE_SEPERATOR).append(sa[1]); + } + return sb.toString(); + } + + /** + * List of String[]{key, value}。转化成list的好处是能保持各feature的顺序。如果输入是空,返回空的List。 + * + * @param featureStr + * @return + */ + public static List convertToList(String featureStr) { + if (StringUtils.isBlank(featureStr)) { + return new ArrayList(); + } + + List featureList = new ArrayList(); + StringTokenizer st = new StringTokenizer(featureStr, FEATURE_SEPERATOR); + + while (st.hasMoreTokens()) { + String kv = st.nextToken(); + + int kvSeperatorIndex = kv.indexOf(KEY_VALUE_SEPERATOR); // index of the key-value seperator. + + if (kvSeperatorIndex > 0) { + String key = kv.substring(0, kvSeperatorIndex); + String value = null; + if (kvSeperatorIndex + 1 < kv.length()) { // deal IndexOutOfBound + value = kv.substring(kvSeperatorIndex + 1); + } else { + value = ""; + } + featureList.add(new String[] {key, value}); + } + } + + return featureList; + } + + /** + * List 转换成 String + * + * @param interList + * @return + */ + public static String convertList2Str(List interList) { + if (CollectionUtils.isEmpty(interList)) { + return StringUtils.EMPTY; + } + return StringUtils.join(interList, StrPoolConstant.COMMA); + } + + public static List convertStr2LongList(String str) { + if (StringUtils.isEmpty(str)) { + return Lists.newArrayList(); + } + return Arrays.stream(StringUtils.split(str, StrPoolConstant.COMMA)) + .map(Long::parseLong) + .collect(Collectors.toList()); + } + + public static void main(String[] args) { + Map stepPrice = new HashMap(); + + stepPrice.put("stepPrice", "1:100:65*1:200:45"); + + System.out.print(convertFromMap(stepPrice)); + } + +} diff --git a/src/main/java/com/luna/common/text/SessionGenerator.java b/src/main/java/com/luna/common/text/SessionGenerator.java new file mode 100755 index 000000000..b6c811255 --- /dev/null +++ b/src/main/java/com/luna/common/text/SessionGenerator.java @@ -0,0 +1,67 @@ +package com.luna.common.text; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +/** + * sessionId生成方式 + */ +public class SessionGenerator { + + private static Map cache = new HashMap(); + private final static String DEFAULT_KEY = "DEFAULT"; + + private static UUID getDefaultUUID() { + UUID u = cache.get(DEFAULT_KEY); + + if(u == null) { + u = UUID.randomUUID(); + cache.put(DEFAULT_KEY, u); + } + return u; + } + + /** + * 去掉UUID小号性能的算法,自定义一个不重复的sessionId生成器 + * @return + */ + public static String generateSessionId() { + UUID u = getDefaultUUID(); + String prefix = toHex(u.getLeastSignificantBits(), 16); + String key0 = toHex((Thread.currentThread().getId()), 4); + String key1 = toHex(System.currentTimeMillis(), 8); + String key2 = toHex(System.nanoTime(), 8); + return prefix + key0 + key1 + key2; + } + + private static String toHex(long i, int len) { + char[] buf = new char[64]; + Arrays.fill(buf, '0'); + int charPos = 64; + int radix = 1 << 4; + long mask = radix - 1; + do { + buf[--charPos] = digits[(int)(i & mask)]; + i >>>= 4; + } while (i != 0); + return new String(buf, (64 - len), len); + } + + final static char[] digits = { + '0' , '1' , '2' , '3' , '4' , '5' , + '6' , '7' , '8' , '9' , 'a' , 'b' , + 'c' , 'd' , 'e' , 'f' , 'g' , 'h' , + 'i' , 'j' , 'k' , 'l' , 'm' , 'n' , + 'o' , 'p' , 'q' , 'r' , 's' , 't' , + 'u' , 'v' , 'w' , 'x' , 'y' , 'z' + }; + + public static void main(String[] a) { + System.out.println(toHex(0x112, 10)); + System.out.println(toHex(0x131412, 3)); + System.out.println(generateSessionId()); + } + +} diff --git a/src/main/java/com/luna/common/thread/AsyncEngineUtils.java b/src/main/java/com/luna/common/thread/AsyncEngineUtils.java index 2a0de1e11..abca9052c 100644 --- a/src/main/java/com/luna/common/thread/AsyncEngineUtils.java +++ b/src/main/java/com/luna/common/thread/AsyncEngineUtils.java @@ -1,8 +1,11 @@ package com.luna.common.thread; +import java.util.ArrayList; import java.util.List; import java.util.concurrent.*; +import org.apache.commons.collections4.CollectionUtils; +import org.checkerframework.checker.nullness.qual.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -15,7 +18,7 @@ public class AsyncEngineUtils { private static final Logger log = LoggerFactory.getLogger(AsyncEngineUtils.class); - private static final int CORE_POOL_SIZE = 10; + private static final int CORE_POOL_SIZE = 100; private static final int MAX_POOL_SIZE = 200; @@ -45,6 +48,21 @@ public static List concurrentExecute(Callable... tasks) { return concurrentExecute(-1, null, tasks); } + /** + * 并发执行具有同样返回值的任务 + * + * @param tasks 任务 + * @return T 任务返回值 + */ + public static List concurrentExecute(List> tasks) { + + if (CollectionUtils.isEmpty(tasks)) { + return Lists.newArrayList(); + } + + return concurrentExecute(tasks.toArray(new Callable[tasks.size()])); + } + /** * 并发执行超时控制任务; 如果某任务超时或发生其他异常,则该任务返回值为null * @@ -93,7 +111,15 @@ public static void execute(Runnable task) { executor.submit(task); } - public static ExecutorService getExecutor() { - return executor; + public static void main(String[] args) { + List> list = Lists.newArrayList(); + for (int i = 0; i < 3; i++) { + list.add(() -> { + System.out.println("hello"); + return null; + }); + } + List voids = concurrentExecute(list); + System.out.println(voids); } } \ No newline at end of file diff --git a/src/main/java/com/luna/common/thread/CommonThreadPoolUtil.java b/src/main/java/com/luna/common/thread/CommonThreadPoolUtil.java index 9852b44ed..979fb4c28 100644 --- a/src/main/java/com/luna/common/thread/CommonThreadPoolUtil.java +++ b/src/main/java/com/luna/common/thread/CommonThreadPoolUtil.java @@ -2,11 +2,9 @@ import java.util.ArrayList; import java.util.List; -import java.util.concurrent.Callable; -import java.util.concurrent.Future; -import java.util.concurrent.LinkedBlockingDeque; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.*; +import org.apache.commons.collections4.CollectionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -27,22 +25,22 @@ public class CommonThreadPoolUtil { private static final long KEEP_ALIVE_TIME = 0L; private static final Logger log = LoggerFactory.getLogger(CommonThreadPoolUtil.class); /** 核心线程数(默认初始化为10) */ - private static int cacheCorePoolSize = 10; + private static volatile int cacheCorePoolSize = 5; /** 核心线程控制的最大数目 */ - private static int maxCorePoolSize = 160; + private static volatile int maxCorePoolSize = 50; /** 队列等待线程数阈值 */ - private static int blockingQueueWaitSize = 16; + private static volatile int blockingQueueWaitSize = 2000; /** 核心线程数自动调整的增量幅度 */ - private static int incrementCorePoolSize = 4; + private static volatile int incrementCorePoolSize = 4; /** 初始化线程池 */ - private static MyselfThreadPoolExecutor threadPool = - new MyselfThreadPoolExecutor(cacheCorePoolSize, cacheCorePoolSize, KEEP_ALIVE_TIME, + private static ThreadPoolExecutor threadPool = + new ThreadPoolExecutor(cacheCorePoolSize, cacheCorePoolSize, KEEP_ALIVE_TIME, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<>()); /** 初始化线程对象ThreadLocal,重写initialValue(),保证ThreadLocal首次执行get方法时不会null异常 */ private final ThreadLocal>> threadLocal = ThreadLocal.withInitial(ArrayList::new); - public static void refresh() { - threadPool = new MyselfThreadPoolExecutor(cacheCorePoolSize, cacheCorePoolSize, KEEP_ALIVE_TIME, + public synchronized static void refresh() { + threadPool = new ThreadPoolExecutor(cacheCorePoolSize, maxCorePoolSize, KEEP_ALIVE_TIME, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<>()); } @@ -69,7 +67,7 @@ public ResultDTO dealTask(Callable callable) { // 设置最新的threadLocal变量到当前主进程 threadLocal.set(threadLocalResult); } catch (Exception e) { - e.printStackTrace(); + log.error("dealTask::callable = {} ", callable, e); return ResultDTOUtils.failure(ResultCode.ERROR_SYSTEM_EXCEPTION, "线程池发生异常-Future"); } return ResultDTOUtils.success(); @@ -93,7 +91,7 @@ public ResultDTO dealTask(Runnable runnable) { // 执行线程业务逻辑 threadPool.execute(runnable); } catch (Exception e) { - e.printStackTrace(); + log.error("dealTask::runnable = {} ", runnable, e); return ResultDTOUtils.failure(ResultCode.ERROR_SYSTEM_EXCEPTION, "线程池发生异常"); } return ResultDTOUtils.success(); @@ -113,7 +111,7 @@ public ResultDTO obtainTaskFuture() { try { // 获取当前进程变量 threadLocalResult = threadLocal.get(); - if (threadLocalResult == null || threadLocalResult.size() == 0) { + if (CollectionUtils.isEmpty(threadLocalResult)) { return ResultDTOUtils.failure(ResultCode.PARAMETER_INVALID, "获取线程池执行结果为空", null); } return ResultDTOUtils.success(threadLocalResult); @@ -136,7 +134,7 @@ public ResultDTO obtainTaskFuture() { private void dynamicTuningPoolSize() { // 队列等待任务数(此为近似值,故采用>=判断) - int queueSize = threadPool.getQueueSize(); + int queueSize = threadPool.getQueue().size(); // 动态更改核心线程数大小 if (queueSize >= blockingQueueWaitSize) { // 核心线程数小于设定的最大线程数才会自动扩展线程数 @@ -177,4 +175,17 @@ public void setCacheCorePoolSize(int cacheCorePoolSize) { threadPool.setMaximumPoolSize(cacheCorePoolSize); CommonThreadPoolUtil.cacheCorePoolSize = cacheCorePoolSize; } + + public static void main(String[] args) { + CommonThreadPoolUtil commonThreadPoolUtil = new CommonThreadPoolUtil(); + commonThreadPoolUtil.setCacheCorePoolSize(20); + for (int i = 0; i < 100; i++) { + commonThreadPoolUtil.dealTask((Callable)() -> { + System.out.println("线程池执行任务"); + return "线程池执行任务"; + }); + } + ResultDTO objectResultDTO = commonThreadPoolUtil.obtainTaskFuture(); + System.out.println(objectResultDTO); + } } diff --git a/src/main/java/com/luna/common/thread/MyselfThreadPoolExecutor.java b/src/main/java/com/luna/common/thread/MyselfThreadPoolExecutor.java deleted file mode 100644 index cb174a30d..000000000 --- a/src/main/java/com/luna/common/thread/MyselfThreadPoolExecutor.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.luna.common.thread; - -import java.util.List; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; - -public class MyselfThreadPoolExecutor extends ThreadPoolExecutor { - - /** 初始化父类构造函数及startTime */ - public MyselfThreadPoolExecutor(int corePoolSize, int maximumPoolSize, - long keepAliveTime, TimeUnit unit, BlockingQueue workQueue) { - - super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); - } - - /** 按过去执行已提交任务的顺序发起一个有序的关闭,但是不接受新任务(已执行的任务不会停止) */ - @Override - public void shutdown() { - - super.shutdown(); - - } - - /** 尝试停止所有的活动执行任务、暂停等待任务的处理,并返回等待执行的任务列表。在从此方法返回的任务队列中排空(移除)这些任务。并不保证能够停止正在处理的活动执行任务,但是会尽力尝试。 */ - @Override - public List shutdownNow() { - - return super.shutdownNow(); - - } - - /** 在执行给定线程中的给定 Runnable 之前调用的方法.可用于重新初始化ThreadLocals或者执行日志记录。 */ - @Override - protected void beforeExecute(Thread t, Runnable r) { - - super.beforeExecute(t, r); - } - - /** 基于完成执行给定 Runnable 所调用的方法 */ - @Override - protected void afterExecute(Runnable r, Throwable t) { - super.afterExecute(r, t); - } - - /** - * - * getQueueSize:(已执行的任务数).
- * - * @author - * @return - */ - @Override - public long getCompletedTaskCount() { - - return super.getCompletedTaskCount(); - } - - /** - * - * getQueueSize:(正在运行的任务数).
- * - * @author - * @return - */ - @Override - public int getActiveCount() { - - return super.getActiveCount(); - } - - /** - * - * getQueueSize:(队列等待任务数).
- * - * @author - * @return - */ - public int getQueueSize() { - - return getQueue().size(); - } -} \ No newline at end of file diff --git a/src/main/java/com/luna/common/thread/AsyncExecuter.java b/src/main/java/com/luna/common/thread/ScheduledAsyncExecutor.java similarity index 66% rename from src/main/java/com/luna/common/thread/AsyncExecuter.java rename to src/main/java/com/luna/common/thread/ScheduledAsyncExecutor.java index bc46b36f2..8d93ab5b9 100644 --- a/src/main/java/com/luna/common/thread/AsyncExecuter.java +++ b/src/main/java/com/luna/common/thread/ScheduledAsyncExecutor.java @@ -1,23 +1,20 @@ package com.luna.common.thread; -import java.util.concurrent.*; +import lombok.SneakyThrows; + +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; import java.util.function.*; /** * @author luna */ -public class AsyncExecuter { - - private static final Executor executor = - new ThreadPoolExecutor(2, 50, 500, TimeUnit.SECONDS, new LinkedBlockingDeque<>(), - runnable -> new Thread(runnable, "AsyncExecuter-" + Thread.currentThread().getName())); +public class ScheduledAsyncExecutor { private static final ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(5, - runnable -> new Thread(runnable, "AsyncExecuter-" + Thread.currentThread().getName())); - public static void submit(final Runnable runnable) { - executor.execute(runnable); - } + runnable -> new Thread(runnable, "ScheduledAsyncExecute-" + Thread.currentThread().getName())); /** * 无入参,无返回值的异步执行方法 , void noStaticFoo() @@ -51,7 +48,7 @@ public static

Future async(Consumer

method, P param) { * @param 第二个入参类型 * @return Future对象,用以判断是否执行结束 */ - public static Future async(BiConsumer method, P1 param1, P2 param2) { + public static Future submit(BiConsumer method, P1 param1, P2 param2) { return scheduledThreadPoolExecutor.submit(() -> method.accept(param1, param2)); } @@ -62,10 +59,14 @@ public static Future async(BiConsumer method, P1 param1, P2 par * @param 返回值类型,如 Entity * @return Future对象,用以判断是否执行结束、获取返回结果 */ - public static Future async(Supplier method) { + public static Future submit(Supplier method) { return scheduledThreadPoolExecutor.submit(method::get); } + public static Future submit(Runnable task, T result) { + return scheduledThreadPoolExecutor.submit(task, result); + } + /** * 单个入参,有返回值的异步执行方法 , Entity noStaticFoo(Long id) * @@ -75,7 +76,7 @@ public static Future async(Supplier method) { * @param 返回值类型,如 Entity * @return Future对象,用以判断是否执行结束、获取返回结果 */ - public static Future async(Function method, P param) { + public static Future submit(Function method, P param) { return scheduledThreadPoolExecutor.submit(() -> method.apply(param)); } @@ -93,4 +94,28 @@ public static Future async(Function method, P param) { public static Future async(BiFunction method, P1 param1, P2 param2) { return scheduledThreadPoolExecutor.submit(() -> method.apply(param1, param2)); } + + /** + * 延迟执行 + * + * @param method + * @param initialDelay + * @param delay + * @param unit + */ + public static

void scheduleWithFixedDelay(Consumer

method, P param1, long initialDelay, long delay, TimeUnit unit) { + scheduledThreadPoolExecutor.scheduleWithFixedDelay(() -> method.accept(param1), initialDelay, delay, unit); + } + + public static

void scheduleWithFixedDelay(Runnable runnable, long initialDelay, long delay, TimeUnit unit) { + scheduledThreadPoolExecutor.scheduleWithFixedDelay(runnable, initialDelay, delay, unit); + } + + @SneakyThrows + public static void main(String[] args) { + scheduleWithFixedDelay(() -> System.out.println("hello"), 1, 1, TimeUnit.SECONDS); + Future hello = submit(() -> "helloFuture"); + Object o = hello.get(); + System.out.println(o); + } } \ No newline at end of file