Java线程池技术

╰+攻爆jí腚メ 2022-07-13 06:47 281阅读 0赞

线程池的优点

1、线程是稀缺资源,使用线程池可以减少创建和销毁线程的次数,每个工作线程都可以重复使用。

2、可以根据系统的承受能力,调整线程池中工作线程的数量,防止因为消耗过多内存导致服务器崩溃。

线程池的创建

  1. public static ExecutorService newCachedThreadPool() {
  2. return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
  3. 60L, TimeUnit.SECONDS,
  4. new SynchronousQueue<Runnable>());
  5. }
  6. public ThreadPoolExecutor(int corePoolSize,
  7. int maximumPoolSize,
  8. long keepAliveTime,
  9. TimeUnit unit,
  10. BlockingQueue<Runnable> workQueue,
  11. ThreadFactory threadFactory,
  12. RejectedExecutionHandler handler) {
  13. if (corePoolSize < 0 ||
  14. maximumPoolSize <= 0 ||
  15. maximumPoolSize < corePoolSize ||
  16. keepAliveTime < 0)
  17. throw new IllegalArgumentException();
  18. if (workQueue == null || threadFactory == null || handler == null)
  19. throw new NullPointerException();
  20. this.corePoolSize = corePoolSize;
  21. this.maximumPoolSize = maximumPoolSize;
  22. this.workQueue = workQueue;
  23. this.keepAliveTime = unit.toNanos(keepAliveTime);
  24. this.threadFactory = threadFactory;
  25. this.handler = handler;
  26. }

corePoolSize:线程池核心线程数量

maximumPoolSize:线程池最大线程数量

keepAliverTime:当活跃线程数大于核心线程数时,空闲的多余线程最大存活时间

unit:存活时间的单位

workQueue:存放任务的队列

handler:超出线程范围和队列容量的任务的处理程序

线程池的实现原理

提交一个任务到线程池中,线程池的处理流程如下:

1、判断线程池里的核心线程是否都在执行任务,如果不是(核心线程空闲或者还有核心线程没有被创建)则创建一个新的工作线程来执行任务。如果核心线程都在执行任务,则进入下个流程。

2、线程池判断工作队列是否已满,如果工作队列没有满,则将新提交的任务存储在这个工作队列里。如果工作队列满了,则进入下个流程。

3、判断线程池里的线程是否都处于工作状态,如果没有,则创建一个新的工作线程来执行任务。如果已经满了,则交给饱和策略来处理这个任务。

Executors方法

生成线程池采用了工具类Executors的静态方法,以下是几种常见的线程池。

newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。

newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。

newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。

newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

  1. /* * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * * * * * * * * * * * * * * * * * * * * */
  2. /* * * * * * * Written by Doug Lea with assistance from members of JCP JSR-166 * Expert Group and released to the public domain, as explained at * http://creativecommons.org/publicdomain/zero/1.0/ */
  3. package java.util.concurrent;
  4. import java.util.*;
  5. import java.util.concurrent.atomic.AtomicInteger;
  6. import java.security.AccessControlContext;
  7. import java.security.AccessController;
  8. import java.security.PrivilegedAction;
  9. import java.security.PrivilegedExceptionAction;
  10. import java.security.PrivilegedActionException;
  11. import java.security.AccessControlException;
  12. import sun.security.util.SecurityConstants;
  13. /** * Factory and utility methods for {@link Executor}, {@link * ExecutorService}, {@link ScheduledExecutorService}, {@link * ThreadFactory}, and {@link Callable} classes defined in this * package. This class supports the following kinds of methods: * * <ul> * <li> Methods that create and return an {@link ExecutorService} * set up with commonly useful configuration settings. * <li> Methods that create and return a {@link ScheduledExecutorService} * set up with commonly useful configuration settings. * <li> Methods that create and return a "wrapped" ExecutorService, that * disables reconfiguration by making implementation-specific methods * inaccessible. * <li> Methods that create and return a {@link ThreadFactory} * that sets newly created threads to a known state. * <li> Methods that create and return a {@link Callable} * out of other closure-like forms, so they can be used * in execution methods requiring <tt>Callable</tt>. * </ul> * * @since 1.5 * @author Doug Lea */
  14. public class Executors {
  15. /** * Creates a thread pool that reuses a fixed number of threads * operating off a shared unbounded queue. At any point, at most * <tt>nThreads</tt> threads will be active processing tasks. * If additional tasks are submitted when all threads are active, * they will wait in the queue until a thread is available. * If any thread terminates due to a failure during execution * prior to shutdown, a new one will take its place if needed to * execute subsequent tasks. The threads in the pool will exist * until it is explicitly {@link ExecutorService#shutdown shutdown}. * * @param nThreads the number of threads in the pool * @return the newly created thread pool * @throws IllegalArgumentException if {@code nThreads <= 0} */
  16. public static ExecutorService newFixedThreadPool(int nThreads) {
  17. return new ThreadPoolExecutor(nThreads, nThreads,
  18. 0L, TimeUnit.MILLISECONDS,
  19. new LinkedBlockingQueue<Runnable>());
  20. }
  21. /** * Creates a thread pool that reuses a fixed number of threads * operating off a shared unbounded queue, using the provided * ThreadFactory to create new threads when needed. At any point, * at most <tt>nThreads</tt> threads will be active processing * tasks. If additional tasks are submitted when all threads are * active, they will wait in the queue until a thread is * available. If any thread terminates due to a failure during * execution prior to shutdown, a new one will take its place if * needed to execute subsequent tasks. The threads in the pool will * exist until it is explicitly {@link ExecutorService#shutdown * shutdown}. * * @param nThreads the number of threads in the pool * @param threadFactory the factory to use when creating new threads * @return the newly created thread pool * @throws NullPointerException if threadFactory is null * @throws IllegalArgumentException if {@code nThreads <= 0} */
  22. public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
  23. return new ThreadPoolExecutor(nThreads, nThreads,
  24. 0L, TimeUnit.MILLISECONDS,
  25. new LinkedBlockingQueue<Runnable>(),
  26. threadFactory);
  27. }
  28. /** * Creates an Executor that uses a single worker thread operating * off an unbounded queue. (Note however that if this single * thread terminates due to a failure during execution prior to * shutdown, a new one will take its place if needed to execute * subsequent tasks.) Tasks are guaranteed to execute * sequentially, and no more than one task will be active at any * given time. Unlike the otherwise equivalent * <tt>newFixedThreadPool(1)</tt> the returned executor is * guaranteed not to be reconfigurable to use additional threads. * * @return the newly created single-threaded Executor */
  29. public static ExecutorService newSingleThreadExecutor() {
  30. return new FinalizableDelegatedExecutorService
  31. (new ThreadPoolExecutor(1, 1,
  32. 0L, TimeUnit.MILLISECONDS,
  33. new LinkedBlockingQueue<Runnable>()));
  34. }
  35. /** * Creates an Executor that uses a single worker thread operating * off an unbounded queue, and uses the provided ThreadFactory to * create a new thread when needed. Unlike the otherwise * equivalent <tt>newFixedThreadPool(1, threadFactory)</tt> the * returned executor is guaranteed not to be reconfigurable to use * additional threads. * * @param threadFactory the factory to use when creating new * threads * * @return the newly created single-threaded Executor * @throws NullPointerException if threadFactory is null */
  36. public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
  37. return new FinalizableDelegatedExecutorService
  38. (new ThreadPoolExecutor(1, 1,
  39. 0L, TimeUnit.MILLISECONDS,
  40. new LinkedBlockingQueue<Runnable>(),
  41. threadFactory));
  42. }
  43. /** * Creates a thread pool that creates new threads as needed, but * will reuse previously constructed threads when they are * available. These pools will typically improve the performance * of programs that execute many short-lived asynchronous tasks. * Calls to <tt>execute</tt> will reuse previously constructed * threads if available. If no existing thread is available, a new * thread will be created and added to the pool. Threads that have * not been used for sixty seconds are terminated and removed from * the cache. Thus, a pool that remains idle for long enough will * not consume any resources. Note that pools with similar * properties but different details (for example, timeout parameters) * may be created using {@link ThreadPoolExecutor} constructors. * * @return the newly created thread pool */
  44. public static ExecutorService newCachedThreadPool() {
  45. return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
  46. 60L, TimeUnit.SECONDS,
  47. new SynchronousQueue<Runnable>());
  48. }
  49. /** * Creates a thread pool that creates new threads as needed, but * will reuse previously constructed threads when they are * available, and uses the provided * ThreadFactory to create new threads when needed. * @param threadFactory the factory to use when creating new threads * @return the newly created thread pool * @throws NullPointerException if threadFactory is null */
  50. public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
  51. return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
  52. 60L, TimeUnit.SECONDS,
  53. new SynchronousQueue<Runnable>(),
  54. threadFactory);
  55. }
  56. /** * Creates a single-threaded executor that can schedule commands * to run after a given delay, or to execute periodically. * (Note however that if this single * thread terminates due to a failure during execution prior to * shutdown, a new one will take its place if needed to execute * subsequent tasks.) Tasks are guaranteed to execute * sequentially, and no more than one task will be active at any * given time. Unlike the otherwise equivalent * <tt>newScheduledThreadPool(1)</tt> the returned executor is * guaranteed not to be reconfigurable to use additional threads. * @return the newly created scheduled executor */
  57. public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
  58. return new DelegatedScheduledExecutorService
  59. (new ScheduledThreadPoolExecutor(1));
  60. }
  61. /** * Creates a single-threaded executor that can schedule commands * to run after a given delay, or to execute periodically. (Note * however that if this single thread terminates due to a failure * during execution prior to shutdown, a new one will take its * place if needed to execute subsequent tasks.) Tasks are * guaranteed to execute sequentially, and no more than one task * will be active at any given time. Unlike the otherwise * equivalent <tt>newScheduledThreadPool(1, threadFactory)</tt> * the returned executor is guaranteed not to be reconfigurable to * use additional threads. * @param threadFactory the factory to use when creating new * threads * @return a newly created scheduled executor * @throws NullPointerException if threadFactory is null */
  62. public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) {
  63. return new DelegatedScheduledExecutorService
  64. (new ScheduledThreadPoolExecutor(1, threadFactory));
  65. }
  66. /** * Creates a thread pool that can schedule commands to run after a * given delay, or to execute periodically. * @param corePoolSize the number of threads to keep in the pool, * even if they are idle. * @return a newly created scheduled thread pool * @throws IllegalArgumentException if {@code corePoolSize < 0} */
  67. public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
  68. return new ScheduledThreadPoolExecutor(corePoolSize);
  69. }
  70. /** * Creates a thread pool that can schedule commands to run after a * given delay, or to execute periodically. * @param corePoolSize the number of threads to keep in the pool, * even if they are idle. * @param threadFactory the factory to use when the executor * creates a new thread. * @return a newly created scheduled thread pool * @throws IllegalArgumentException if {@code corePoolSize < 0} * @throws NullPointerException if threadFactory is null */
  71. public static ScheduledExecutorService newScheduledThreadPool(
  72. int corePoolSize, ThreadFactory threadFactory) {
  73. return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
  74. }
  75. /** * Returns an object that delegates all defined {@link * ExecutorService} methods to the given executor, but not any * other methods that might otherwise be accessible using * casts. This provides a way to safely "freeze" configuration and * disallow tuning of a given concrete implementation. * @param executor the underlying implementation * @return an <tt>ExecutorService</tt> instance * @throws NullPointerException if executor null */
  76. public static ExecutorService unconfigurableExecutorService(ExecutorService executor) {
  77. if (executor == null)
  78. throw new NullPointerException();
  79. return new DelegatedExecutorService(executor);
  80. }
  81. /** * Returns an object that delegates all defined {@link * ScheduledExecutorService} methods to the given executor, but * not any other methods that might otherwise be accessible using * casts. This provides a way to safely "freeze" configuration and * disallow tuning of a given concrete implementation. * @param executor the underlying implementation * @return a <tt>ScheduledExecutorService</tt> instance * @throws NullPointerException if executor null */
  82. public static ScheduledExecutorService unconfigurableScheduledExecutorService(ScheduledExecutorService executor) {
  83. if (executor == null)
  84. throw new NullPointerException();
  85. return new DelegatedScheduledExecutorService(executor);
  86. }
  87. /** * Returns a default thread factory used to create new threads. * This factory creates all new threads used by an Executor in the * same {@link ThreadGroup}. If there is a {@link * java.lang.SecurityManager}, it uses the group of {@link * System#getSecurityManager}, else the group of the thread * invoking this <tt>defaultThreadFactory</tt> method. Each new * thread is created as a non-daemon thread with priority set to * the smaller of <tt>Thread.NORM_PRIORITY</tt> and the maximum * priority permitted in the thread group. New threads have names * accessible via {@link Thread#getName} of * <em>pool-N-thread-M</em>, where <em>N</em> is the sequence * number of this factory, and <em>M</em> is the sequence number * of the thread created by this factory. * @return a thread factory */
  88. public static ThreadFactory defaultThreadFactory() {
  89. return new DefaultThreadFactory();
  90. }
  91. /** * Returns a thread factory used to create new threads that * have the same permissions as the current thread. * This factory creates threads with the same settings as {@link * Executors#defaultThreadFactory}, additionally setting the * AccessControlContext and contextClassLoader of new threads to * be the same as the thread invoking this * <tt>privilegedThreadFactory</tt> method. A new * <tt>privilegedThreadFactory</tt> can be created within an * {@link AccessController#doPrivileged} action setting the * current thread's access control context to create threads with * the selected permission settings holding within that action. * * <p> Note that while tasks running within such threads will have * the same access control and class loader settings as the * current thread, they need not have the same {@link * java.lang.ThreadLocal} or {@link * java.lang.InheritableThreadLocal} values. If necessary, * particular values of thread locals can be set or reset before * any task runs in {@link ThreadPoolExecutor} subclasses using * {@link ThreadPoolExecutor#beforeExecute}. Also, if it is * necessary to initialize worker threads to have the same * InheritableThreadLocal settings as some other designated * thread, you can create a custom ThreadFactory in which that * thread waits for and services requests to create others that * will inherit its values. * * @return a thread factory * @throws AccessControlException if the current access control * context does not have permission to both get and set context * class loader. */
  92. public static ThreadFactory privilegedThreadFactory() {
  93. return new PrivilegedThreadFactory();
  94. }
  95. /** * Returns a {@link Callable} object that, when * called, runs the given task and returns the given result. This * can be useful when applying methods requiring a * <tt>Callable</tt> to an otherwise resultless action. * @param task the task to run * @param result the result to return * @return a callable object * @throws NullPointerException if task null */
  96. public static <T> Callable<T> callable(Runnable task, T result) {
  97. if (task == null)
  98. throw new NullPointerException();
  99. return new RunnableAdapter<T>(task, result);
  100. }
  101. /** * Returns a {@link Callable} object that, when * called, runs the given task and returns <tt>null</tt>. * @param task the task to run * @return a callable object * @throws NullPointerException if task null */
  102. public static Callable<Object> callable(Runnable task) {
  103. if (task == null)
  104. throw new NullPointerException();
  105. return new RunnableAdapter<Object>(task, null);
  106. }
  107. /** * Returns a {@link Callable} object that, when * called, runs the given privileged action and returns its result. * @param action the privileged action to run * @return a callable object * @throws NullPointerException if action null */
  108. public static Callable<Object> callable(final PrivilegedAction<?> action) {
  109. if (action == null)
  110. throw new NullPointerException();
  111. return new Callable<Object>() {
  112. public Object call() { return action.run(); }};
  113. }
  114. /** * Returns a {@link Callable} object that, when * called, runs the given privileged exception action and returns * its result. * @param action the privileged exception action to run * @return a callable object * @throws NullPointerException if action null */
  115. public static Callable<Object> callable(final PrivilegedExceptionAction<?> action) {
  116. if (action == null)
  117. throw new NullPointerException();
  118. return new Callable<Object>() {
  119. public Object call() throws Exception { return action.run(); }};
  120. }
  121. /** * Returns a {@link Callable} object that will, when * called, execute the given <tt>callable</tt> under the current * access control context. This method should normally be * invoked within an {@link AccessController#doPrivileged} action * to create callables that will, if possible, execute under the * selected permission settings holding within that action; or if * not possible, throw an associated {@link * AccessControlException}. * @param callable the underlying task * @return a callable object * @throws NullPointerException if callable null * */
  122. public static <T> Callable<T> privilegedCallable(Callable<T> callable) {
  123. if (callable == null)
  124. throw new NullPointerException();
  125. return new PrivilegedCallable<T>(callable);
  126. }
  127. /** * Returns a {@link Callable} object that will, when * called, execute the given <tt>callable</tt> under the current * access control context, with the current context class loader * as the context class loader. This method should normally be * invoked within an {@link AccessController#doPrivileged} action * to create callables that will, if possible, execute under the * selected permission settings holding within that action; or if * not possible, throw an associated {@link * AccessControlException}. * @param callable the underlying task * * @return a callable object * @throws NullPointerException if callable null * @throws AccessControlException if the current access control * context does not have permission to both set and get context * class loader. */
  128. public static <T> Callable<T> privilegedCallableUsingCurrentClassLoader(Callable<T> callable) {
  129. if (callable == null)
  130. throw new NullPointerException();
  131. return new PrivilegedCallableUsingCurrentClassLoader<T>(callable);
  132. }
  133. // Non-public classes supporting the public methods
  134. /** * A callable that runs given task and returns given result */
  135. static final class RunnableAdapter<T> implements Callable<T> {
  136. final Runnable task;
  137. final T result;
  138. RunnableAdapter(Runnable task, T result) {
  139. this.task = task;
  140. this.result = result;
  141. }
  142. public T call() {
  143. task.run();
  144. return result;
  145. }
  146. }
  147. /** * A callable that runs under established access control settings */
  148. static final class PrivilegedCallable<T> implements Callable<T> {
  149. private final Callable<T> task;
  150. private final AccessControlContext acc;
  151. PrivilegedCallable(Callable<T> task) {
  152. this.task = task;
  153. this.acc = AccessController.getContext();
  154. }
  155. public T call() throws Exception {
  156. try {
  157. return AccessController.doPrivileged(
  158. new PrivilegedExceptionAction<T>() {
  159. public T run() throws Exception {
  160. return task.call();
  161. }
  162. }, acc);
  163. } catch (PrivilegedActionException e) {
  164. throw e.getException();
  165. }
  166. }
  167. }
  168. /** * A callable that runs under established access control settings and * current ClassLoader */
  169. static final class PrivilegedCallableUsingCurrentClassLoader<T> implements Callable<T> {
  170. private final Callable<T> task;
  171. private final AccessControlContext acc;
  172. private final ClassLoader ccl;
  173. PrivilegedCallableUsingCurrentClassLoader(Callable<T> task) {
  174. SecurityManager sm = System.getSecurityManager();
  175. if (sm != null) {
  176. // Calls to getContextClassLoader from this class
  177. // never trigger a security check, but we check
  178. // whether our callers have this permission anyways.
  179. sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
  180. // Whether setContextClassLoader turns out to be necessary
  181. // or not, we fail fast if permission is not available.
  182. sm.checkPermission(new RuntimePermission("setContextClassLoader"));
  183. }
  184. this.task = task;
  185. this.acc = AccessController.getContext();
  186. this.ccl = Thread.currentThread().getContextClassLoader();
  187. }
  188. public T call() throws Exception {
  189. try {
  190. return AccessController.doPrivileged(
  191. new PrivilegedExceptionAction<T>() {
  192. public T run() throws Exception {
  193. Thread t = Thread.currentThread();
  194. ClassLoader cl = t.getContextClassLoader();
  195. if (ccl == cl) {
  196. return task.call();
  197. } else {
  198. t.setContextClassLoader(ccl);
  199. try {
  200. return task.call();
  201. } finally {
  202. t.setContextClassLoader(cl);
  203. }
  204. }
  205. }
  206. }, acc);
  207. } catch (PrivilegedActionException e) {
  208. throw e.getException();
  209. }
  210. }
  211. }
  212. /** * The default thread factory */
  213. static class DefaultThreadFactory implements ThreadFactory {
  214. private static final AtomicInteger poolNumber = new AtomicInteger(1);
  215. private final ThreadGroup group;
  216. private final AtomicInteger threadNumber = new AtomicInteger(1);
  217. private final String namePrefix;
  218. DefaultThreadFactory() {
  219. SecurityManager s = System.getSecurityManager();
  220. group = (s != null) ? s.getThreadGroup() :
  221. Thread.currentThread().getThreadGroup();
  222. namePrefix = "pool-" +
  223. poolNumber.getAndIncrement() +
  224. "-thread-";
  225. }
  226. public Thread newThread(Runnable r) {
  227. Thread t = new Thread(group, r,
  228. namePrefix + threadNumber.getAndIncrement(),
  229. 0);
  230. if (t.isDaemon())
  231. t.setDaemon(false);
  232. if (t.getPriority() != Thread.NORM_PRIORITY)
  233. t.setPriority(Thread.NORM_PRIORITY);
  234. return t;
  235. }
  236. }
  237. /** * Thread factory capturing access control context and class loader */
  238. static class PrivilegedThreadFactory extends DefaultThreadFactory {
  239. private final AccessControlContext acc;
  240. private final ClassLoader ccl;
  241. PrivilegedThreadFactory() {
  242. super();
  243. SecurityManager sm = System.getSecurityManager();
  244. if (sm != null) {
  245. // Calls to getContextClassLoader from this class
  246. // never trigger a security check, but we check
  247. // whether our callers have this permission anyways.
  248. sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
  249. // Fail fast
  250. sm.checkPermission(new RuntimePermission("setContextClassLoader"));
  251. }
  252. this.acc = AccessController.getContext();
  253. this.ccl = Thread.currentThread().getContextClassLoader();
  254. }
  255. public Thread newThread(final Runnable r) {
  256. return super.newThread(new Runnable() {
  257. public void run() {
  258. AccessController.doPrivileged(new PrivilegedAction<Void>() {
  259. public Void run() {
  260. Thread.currentThread().setContextClassLoader(ccl);
  261. r.run();
  262. return null;
  263. }
  264. }, acc);
  265. }
  266. });
  267. }
  268. }
  269. /** * A wrapper class that exposes only the ExecutorService methods * of an ExecutorService implementation. */
  270. static class DelegatedExecutorService extends AbstractExecutorService {
  271. private final ExecutorService e;
  272. DelegatedExecutorService(ExecutorService executor) { e = executor; }
  273. public void execute(Runnable command) { e.execute(command); }
  274. public void shutdown() { e.shutdown(); }
  275. public List<Runnable> shutdownNow() { return e.shutdownNow(); }
  276. public boolean isShutdown() { return e.isShutdown(); }
  277. public boolean isTerminated() { return e.isTerminated(); }
  278. public boolean awaitTermination(long timeout, TimeUnit unit)
  279. throws InterruptedException {
  280. return e.awaitTermination(timeout, unit);
  281. }
  282. public Future<?> submit(Runnable task) {
  283. return e.submit(task);
  284. }
  285. public <T> Future<T> submit(Callable<T> task) {
  286. return e.submit(task);
  287. }
  288. public <T> Future<T> submit(Runnable task, T result) {
  289. return e.submit(task, result);
  290. }
  291. public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
  292. throws InterruptedException {
  293. return e.invokeAll(tasks);
  294. }
  295. public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
  296. long timeout, TimeUnit unit)
  297. throws InterruptedException {
  298. return e.invokeAll(tasks, timeout, unit);
  299. }
  300. public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
  301. throws InterruptedException, ExecutionException {
  302. return e.invokeAny(tasks);
  303. }
  304. public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
  305. long timeout, TimeUnit unit)
  306. throws InterruptedException, ExecutionException, TimeoutException {
  307. return e.invokeAny(tasks, timeout, unit);
  308. }
  309. }
  310. static class FinalizableDelegatedExecutorService
  311. extends DelegatedExecutorService {
  312. FinalizableDelegatedExecutorService(ExecutorService executor) {
  313. super(executor);
  314. }
  315. protected void finalize() {
  316. super.shutdown();
  317. }
  318. }
  319. /** * A wrapper class that exposes only the ScheduledExecutorService * methods of a ScheduledExecutorService implementation. */
  320. static class DelegatedScheduledExecutorService
  321. extends DelegatedExecutorService
  322. implements ScheduledExecutorService {
  323. private final ScheduledExecutorService e;
  324. DelegatedScheduledExecutorService(ScheduledExecutorService executor) {
  325. super(executor);
  326. e = executor;
  327. }
  328. public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
  329. return e.schedule(command, delay, unit);
  330. }
  331. public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) {
  332. return e.schedule(callable, delay, unit);
  333. }
  334. public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) {
  335. return e.scheduleAtFixedRate(command, initialDelay, period, unit);
  336. }
  337. public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) {
  338. return e.scheduleWithFixedDelay(command, initialDelay, delay, unit);
  339. }
  340. }
  341. /** Cannot instantiate. */
  342. private Executors() {}
  343. }

*execute()方法实际上是Executor中声明的方法,在ThreadPoolExecutor进行了具体的实现,这个方法是ThreadPoolExecutor的核心方法,通过这个方法可以向线程池提交一个任务,交由线程池去执行。
  submit()方法是在ExecutorService中声明的方法,在AbstractExecutorService就已经有了具体的实现,在ThreadPoolExecutor中并没有对其进行重写,这个方法也是用来向线程池提交任务的,但是它和execute()方法不同,它能够返回任务执行的结果,去看submit()方法的实现,会发现它实际上还是调用的execute()方法,只不过它利用了Future来获取任务执行结果(Future相关内容将在下一篇讲述)。
  shutdown()和shutdownNow()是用来关闭线程池的。*

代码示例

  1. package test;
  2. import java.io.IOException;
  3. import java.util.concurrent.ExecutorService;
  4. import java.util.concurrent.Executors;
  5. import java.util.concurrent.Future;
  6. public class Test {
  7. /** * @param args * @throws IOException */
  8. public static void main(String[] args) throws IOException {
  9. ExecutorService executorService = Executors.newCachedThreadPool();
  10. //第一种
  11. Thread t = new Thread(new Test2());
  12. executorService.execute(t);
  13. //第二种 有返回结果
  14. Thread t1 = new Thread(new Test3());
  15. Future<?> future=executorService.submit(t1);
  16. // 第三种
  17. executorService.submit(new Runnable() {
  18. public void run() {
  19. }
  20. });
  21. }
  22. }
  23. class Test2 implements Runnable {
  24. public void run() {
  25. }
  26. }
  27. class Test3 extends Thread {
  28. public void run() {
  29. }
  30. }

发表评论

表情:
评论列表 (有 0 条评论,281人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Java线技术

    线程池的优点 1、线程是稀缺资源,使用线程池可以减少创建和销毁线程的次数,每个工作线程都可以重复使用。 2、可以根据系统的承受能力,调整线程池中工作线程的数量,防止因为消耗

    相关 线技术

    1、线程池技术的简单概括        对于服务端的程序,经常面对的是客户端传入的短小(执行时间短、工作内容较为单一)任务,需要服务端快速处理并返回结果。如果服务端每次接受到

    相关 线技术及其示例

    线程池技术及其示例 线程池技术及其示例 线程池技术及其示例 对于服务端的程序,经常面对成千上万的任务提交到服务器汇总,如果采用一个任务一个线程的方式,那么将