实际多线程例子
一、建立多线程入口bean
@Component public class CallFunction { @Autowired private BatchSendSMSService batchSendSMSService; @Autowired private SmsTransitService smsTransitService; public void smsThread(Map<String, Object> map){ ExecutorServiceUtil.newExecutorService().submit(new Runnable() { @Override public void run() { batchSendSMSService.batchSend(map); } }); } public void ymSmsThread(Map<String, Object> map){ ExecutorServiceUtil.newExecutorService().submit(new Runnable() { @Override public void run() { batchSendSMSService.yMbatchSend(map); } }); } }
二、Executor线程池框架专配类
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.SynchronousQueue; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import ch.qos.logback.core.CoreConstants; /** * Static utility methods for manipulating an {@link ExecutorService}. * * @author Carl Harris * @author Mikhail Mazursky */ public class ExecutorServiceUtil { private static final ThreadFactory THREAD_FACTORY = new ThreadFactory() { private final ThreadFactory defaultFactory = Executors.defaultThreadFactory(); private final AtomicInteger threadNumber = new AtomicInteger(1); public Thread newThread(Runnable r) { Thread thread = defaultFactory.newThread(r); if (!thread.isDaemon()) { thread.setDaemon(true); } thread.setName("logback-" + threadNumber.getAndIncrement()); return thread; } }; /** * Creates an executor service suitable for use by logback components. * @return executor service */ static public ExecutorService newExecutorService() { return new ThreadPoolExecutor(CoreConstants.CORE_POOL_SIZE, CoreConstants.MAX_POOL_SIZE, 0L, TimeUnit.MILLISECONDS, new SynchronousQueue<Runnable>(), THREAD_FACTORY); } /** * Shuts down an executor service. * <p> * @param executorService the executor service to shut down */ static public void shutdown(ExecutorService executorService) { executorService.shutdownNow(); } }
public class CoreConstants { /** * Number of idle threads to retain in a context's executor service. */ // CORE_POOL_SIZE must be 1 for JDK 1.5. For JDK 1.6 or higher it's set to 0 // so that there are no idle threads public static final int CORE_POOL_SIZE = EnvUtil.isJDK5() ? 1 : 0; /** * Maximum number of threads to allow in a context's executor service. */ // if you need a different MAX_POOL_SIZE, please file create a jira issue // asking to make MAX_POOL_SIZE a parameter. public static final int MAX_POOL_SIZE = 32; // Note that the line.separator property can be looked up even by // applets. public static final String LINE_SEPARATOR = System.getProperty("line.separator"); public static final int LINE_SEPARATOR_LEN = LINE_SEPARATOR.length(); public static final String CODES_URL = "http://logback.qos.ch/codes.html"; /** * The default context name. */ public static final String DEFAULT_CONTEXT_NAME = "default"; /** * Customized pattern conversion rules are stored under this key in the * {@link Context} object store. */ public static final String PATTERN_RULE_REGISTRY = "PATTERN_RULE_REGISTRY"; public static final String ISO8601_STR = "ISO8601"; public static final String ISO8601_PATTERN = "yyyy-MM-dd HH:mm:ss,SSS"; public static final String DAILY_DATE_PATTERN = "yyyy-MM-dd"; /** * Time format used in Common Log Format */ public static final String CLF_DATE_PATTERN = "dd/MMM/yyyy:HH:mm:ss Z"; /** * The key used in locating the evaluator map in context's object map. */ public static final String EVALUATOR_MAP = "EVALUATOR_MAP"; /** * By convention, we assume that the static method named "valueOf" taking * a string argument can restore a given object from its string * representation. */ public static final String VALUE_OF = "valueOf"; /** * An empty string. */ public static final String EMPTY_STRING = ""; /** * An empty string array. */ public static final String[] EMPTY_STRING_ARRAY = new String[]{}; /** * An empty Class array. */ public static final Class<?>[] EMPTY_CLASS_ARRAY = new Class[]{}; public static final String CAUSED_BY = "Caused by: "; public static final String SUPPRESSED = "Suppressed: "; public static final String WRAPPED_BY = "Wrapped by: "; public static final char PERCENT_CHAR = '%'; public static final char LEFT_PARENTHESIS_CHAR = '('; public static final char RIGHT_PARENTHESIS_CHAR = ')'; public static final char ESCAPE_CHAR = '\\'; public static final char CURLY_LEFT = '{'; public static final char CURLY_RIGHT = '}'; public static final char COMMA_CHAR = ','; public static final char DOUBLE_QUOTE_CHAR = '"'; public static final char SINGLE_QUOTE_CHAR = '\''; public static final char COLON_CHAR = ':'; public static final char DASH_CHAR = '-'; public static final String DEFAULT_VALUE_SEPARATOR = ":-"; /** * Number of rows before in an HTML table before, * we close the table and create a new one */ public static final int TABLE_ROW_LIMIT = 10000; // reset the ObjectOutputStream every OOS_RESET_FREQUENCY calls // this avoid serious memory leaks public static final int OOS_RESET_FREQUENCY = 70; /** * The reference bogo instructions per second on * Ceki's machine (Orion) */ public static long REFERENCE_BIPS = 9000; // the max number of times an error should be reported public static final int MAX_ERROR_COUNT = 4; public static final char DOT = '.'; public static final char TAB = '\t'; public static final char DOLLAR = '$'; public static final String SEE_FNP_NOT_SET = "See also http://logback.qos.ch/codes.html#tbr_fnp_not_set"; public static final String CONFIGURATION_WATCH_LIST = "CONFIGURATION_WATCH_LIST"; public static final String CONFIGURATION_WATCH_LIST_RESET = "CONFIGURATION_WATCH_LIST_RESET"; public static final String SAFE_JORAN_CONFIGURATION = "SAFE_JORAN_CONFIGURATION"; public static final String XML_PARSING = "XML_PARSING"; // Context Object name for the shutdown hook public static final String SHUTDOWN_HOOK_THREAD = "SHUTDOWN_HOOK"; /** * The key under which the local host name is registered in the logger * context. */ public static final String HOSTNAME_KEY = "HOSTNAME"; /** * The key under which the current context name is registered in the logger * context. */ public static final String CONTEXT_NAME_KEY = "CONTEXT_NAME"; public static final int BYTES_PER_INT = 4; public static final int MILLIS_IN_ONE_SECOND = 1000; public static final int MILLIS_IN_ONE_MINUTE = MILLIS_IN_ONE_SECOND*60; public static final int MILLIS_IN_ONE_HOUR = MILLIS_IN_ONE_MINUTE*60; public static final int MILLIS_IN_ONE_DAY = MILLIS_IN_ONE_HOUR*24; public static final int MILLIS_IN_ONE_WEEK = MILLIS_IN_ONE_DAY*7; /** * The number of seconds to wait for compression jobs to finish. */ public static final int SECONDS_TO_WAIT_FOR_COMPRESSION_JOBS = 30; public static final String CONTEXT_SCOPE_VALUE = "context"; public static final String RESET_MSG_PREFIX = "Will reset and reconfigure context "; public static final String JNDI_COMP_PREFIX = "java:comp/env"; public static final String UNDEFINED_PROPERTY_SUFFIX = "_IS_UNDEFINED"; public static final String LEFT_ACCOLADE = new String(new char[] {CURLY_LEFT}); public static final String RIGHT_ACCOLADE = new String(new char[] {CURLY_RIGHT}); }
public class EnvUtil { static private boolean isJDK_N_OrHigher(int n) { List<String> versionList = new ArrayList<String>(); // this code should work at least until JDK 10 (assuming n parameter is // always 6 or more) for (int i = 0; i < 5; i++) { versionList.add("1." + (n + i)); } String javaVersion = System.getProperty("java.version"); if (javaVersion == null) { return false; } for (String v : versionList) { if (javaVersion.startsWith(v)) return true; } return false; } static public boolean isJDK5() { return isJDK_N_OrHigher(5); } static public boolean isJDK6OrHigher() { return isJDK_N_OrHigher(6); } static public boolean isJDK7OrHigher() { return isJDK_N_OrHigher(7); } static public boolean isJaninoAvailable() { ClassLoader classLoader = EnvUtil.class.getClassLoader(); try { Class<?> bindingClass = classLoader.loadClass("org.codehaus.janino.ScriptEvaluator"); return (bindingClass != null); } catch (ClassNotFoundException e) { return false; } } public static boolean isWindows() { String os = System.getProperty("os.name"); return os.startsWith("Windows"); } }