- 浏览: 497502 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
gaoke:
"我觉得这是java动态生成代码的方式得到的,因为使 ...
InvocationHandler中invoke()方法的调用问题 -
lyandyhk:
可以,反正对于我这个水平来说刚刚好,正好全部看懂,满分
InvocationHandler中invoke()方法的调用问题 -
593844923:
Subject subject=(Subject) Proxy ...
InvocationHandler中invoke()方法的调用问题 -
hl174:
写的不错 源码确实有点长 第一次大致看还有些没看怎么明白
InvocationHandler中invoke()方法的调用问题 -
draem0507:
129应该表示为00000000 10000001,转成byt ...
Java的补码表示
对于多线程有了一点了解之后,那么来看看java.lang.concurrent包下面的一些东西。在此之前,我们运行一个线程都是显式调用了Thread的start()方法。我们用concurrent下面的类来实现一下线程的运行,而且这将成为以后常用的方法或者实现思路。
看一个简单的例子:
这个例子其实很容易看懂,ExecutorService中有一个execute方法,这个方法的参数是Runnable类型。也就是说,将一个实现了Runnable类型的类的实例作为参数传入execute方法并执行,那么线程就相应的执行了。
一、ExecutorService
先看看ExecutorService,这是一个接口,简单的列一下这个接口:
ExecuteService继承了Executor,Executor也是一个接口,里面只有一个方法:
二、Executors
Executors是一个类,直接援引JDK文档的说明来说一下这个类的作用:
在上面的例子中,我们用到了newCachedThreadPool()方法。看一下这个方法:
在源码中我们可以知道两点,1、这个方法返回类型是ExecutorService;2、此方法返回值实际是另一个类的实例。看一下这个类的信息:
ThreadPoolExecutor继承了AbstractExecutorService,而AbstractExecutorService又实现了ExecutorService接口。所以,根据多态,ThreadPoolExecutor可以看作是ExecutorService类型。
线程执行的最关键的一步是执行了executor方法,根据java的动态绑定,实际执行的是ThreadPoolExecutor所实现的executor方法。看看源码:
根据程序正常执行的路线来看,这个方法中比较重要的两个地方分别是:
1、workQueue.offer(command)
workQueue在上面提到过,是BlockingQueue<Runnable>类型的变量,这条语句就是将Runnable类型的实例加入到队列中。
2、ensureQueuedTaskHandled(command)
这个是线程执行的关键语句。看看它的源码:
在这里我们就可以看到最终执行了t.start()方法来运行线程。在这之前的重点是t=addThread(null)方法,看看addThread方法的源码:
这里两个重点,很明显:
1、Worker w = new Worker(firstTask)
2、Thread t = threadFactory.newThread(w)
先看Worker是个什么结构:
Worker是一个内部类。根据之前可以知道,传入addThread的参数是null,也就是说Work中firstTask为null。
在看看newThread是一个什么方法:
通过源码可以得知threadFactory的实际类型是DefaultThreadFactory,而DefaultThreadFactory是Executors的一个嵌套内部类。
之前我们提到了t.start()这个方法执行了线程。那么现在从头顺一下,看看到底是执行了谁的run方法。首先知道,t=addThread(null),而addThread内部执行了下面三步,Worker w = new Worker(null);Thread t = threadFactory.newThread(w);return t;这里两个t是一致的。
从这里可以看出,t.start()实际上执行的是Worker内部的run方法。run()内部会在if条件里面使用“短路”:判断firstTask是否为null,若不是null则直接执行firstTask的run方法;如果是null,则调用getTask()方法来获取Runnable类型实例。从哪里获取呢?workQueue!在execute方法中,执行ensureQueuedTaskHandled(command)之前就已经把Runnable类型实例放入到workQueue中了,所以这里可以从workQueue中获取到。
看一个简单的例子:
public class CacheThreadPool { public static void main(String[] args) { ExecutorService exec=Executors.newCachedThreadPool(); for(int i=0;i<5;i++) exec.execute(new LiftOff()); exec.shutdown();//并不是终止线程的运行,而是禁止在这个Executor中添加新的任务 } }
这个例子其实很容易看懂,ExecutorService中有一个execute方法,这个方法的参数是Runnable类型。也就是说,将一个实现了Runnable类型的类的实例作为参数传入execute方法并执行,那么线程就相应的执行了。
一、ExecutorService
先看看ExecutorService,这是一个接口,简单的列一下这个接口:
public interface ExecutorService extends Executor { void shutdown(); List<Runnable> shutdownNow(); boolean isShutdown(); boolean isTerminated(); boolean awaitTermination(long timeout, TimeUnit unit) <T> Future<T> submit(Callable<T> task); <T> Future<T> submit(Runnable task, T result); Future<?> submit(Runnable task); <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) <T> T invokeAny(Collection<? extends Callable<T>> tasks) <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) }
ExecuteService继承了Executor,Executor也是一个接口,里面只有一个方法:
void execute(Runnable command)
二、Executors
Executors是一个类,直接援引JDK文档的说明来说一下这个类的作用:
- Factory and utility methods for Executor, ExecutorService, ScheduledExecutorService, ThreadFactory, and Callable classes defined in this package. This class supports the following kinds of methods:
- Methods that create and return an ExecutorService set up with commonly useful configuration settings.
- Methods that create and return a ScheduledExecutorService set up with commonly useful configuration settings.
- Methods that create and return a "wrapped" ExecutorService, that disables reconfiguration by making implementation-specific methods inaccessible.
- Methods that create and return a ThreadFactory that sets newly created threads to a known state.
- Methods that create and return a Callable out of other closure-like forms, so they can be used in execution methods requiring Callable.
在上面的例子中,我们用到了newCachedThreadPool()方法。看一下这个方法:
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
在源码中我们可以知道两点,1、这个方法返回类型是ExecutorService;2、此方法返回值实际是另一个类的实例。看一下这个类的信息:
public class ThreadPoolExecutor extends AbstractExecutorService { .......... private final BlockingQueue<Runnable> workQueue;//这个变量在下面会提到 .......... }
ThreadPoolExecutor继承了AbstractExecutorService,而AbstractExecutorService又实现了ExecutorService接口。所以,根据多态,ThreadPoolExecutor可以看作是ExecutorService类型。
线程执行的最关键的一步是执行了executor方法,根据java的动态绑定,实际执行的是ThreadPoolExecutor所实现的executor方法。看看源码:
public class ThreadPoolExecutor extends AbstractExecutorService { .......... public void execute(Runnable command) { if (command == null) throw new NullPointerException(); if (poolSize >= corePoolSize || !addIfUnderCorePoolSize(command)) { if (runState == RUNNING && workQueue.offer(command)) { if (runState != RUNNING || poolSize == 0) ensureQueuedTaskHandled(command); } else if (!addIfUnderMaximumPoolSize(command)) reject(command); // is shutdown or saturated } } .......... }
根据程序正常执行的路线来看,这个方法中比较重要的两个地方分别是:
1、workQueue.offer(command)
workQueue在上面提到过,是BlockingQueue<Runnable>类型的变量,这条语句就是将Runnable类型的实例加入到队列中。
2、ensureQueuedTaskHandled(command)
这个是线程执行的关键语句。看看它的源码:
public class ThreadPoolExecutor extends AbstractExecutorService { .......... private void ensureQueuedTaskHandled(Runnable command) { final ReentrantLock mainLock = this.mainLock; mainLock.lock(); boolean reject = false; Thread t = null; try { int state = runState; if (state != RUNNING && workQueue.remove(command)) reject = true; else if (state < STOP && poolSize < Math.max(corePoolSize, 1) && !workQueue.isEmpty()) t = addThread(null); } finally { mainLock.unlock(); } if (reject) reject(command); else if (t != null) t.start(); } .......... }
在这里我们就可以看到最终执行了t.start()方法来运行线程。在这之前的重点是t=addThread(null)方法,看看addThread方法的源码:
public class ThreadPoolExecutor extends AbstractExecutorService { .......... private Thread addThread(Runnable firstTask) { Worker w = new Worker(firstTask); Thread t = threadFactory.newThread(w); if (t != null) { w.thread = t; workers.add(w); int nt = ++poolSize; if (nt > largestPoolSize) largestPoolSize = nt; } return t; } .......... }
这里两个重点,很明显:
1、Worker w = new Worker(firstTask)
2、Thread t = threadFactory.newThread(w)
先看Worker是个什么结构:
public class ThreadPoolExecutor extends AbstractExecutorService { .......... private final class Worker implements Runnable { .......... Worker(Runnable firstTask) { this.firstTask = firstTask; } private Runnable firstTask; .......... public void run() { try { Runnable task = firstTask; firstTask = null; while (task != null || (task = getTask()) != null) { runTask(task); task = null; } } finally { workerDone(this); } } } Runnable getTask() { for (;;) { try { int state = runState; if (state > SHUTDOWN) return null; Runnable r; if (state == SHUTDOWN) // Help drain queue r = workQueue.poll(); else if (poolSize > corePoolSize || allowCoreThreadTimeOut) r = workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS); else r = workQueue.take(); if (r != null) return r; if (workerCanExit()) { if (runState >= SHUTDOWN) // Wake up others interruptIdleWorkers(); return null; } // Else retry } catch (InterruptedException ie) { // On interruption, re-check runState } } } } .......... }
Worker是一个内部类。根据之前可以知道,传入addThread的参数是null,也就是说Work中firstTask为null。
在看看newThread是一个什么方法:
public class Executors { .......... static class DefaultThreadFactory implements ThreadFactory { .......... public Thread newThread(Runnable r) { Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0); if (t.isDaemon()) t.setDaemon(false); if (t.getPriority() != Thread.NORM_PRIORITY) t.setPriority(Thread.NORM_PRIORITY); return t; } .......... } .......... }
通过源码可以得知threadFactory的实际类型是DefaultThreadFactory,而DefaultThreadFactory是Executors的一个嵌套内部类。
之前我们提到了t.start()这个方法执行了线程。那么现在从头顺一下,看看到底是执行了谁的run方法。首先知道,t=addThread(null),而addThread内部执行了下面三步,Worker w = new Worker(null);Thread t = threadFactory.newThread(w);return t;这里两个t是一致的。
从这里可以看出,t.start()实际上执行的是Worker内部的run方法。run()内部会在if条件里面使用“短路”:判断firstTask是否为null,若不是null则直接执行firstTask的run方法;如果是null,则调用getTask()方法来获取Runnable类型实例。从哪里获取呢?workQueue!在execute方法中,执行ensureQueuedTaskHandled(command)之前就已经把Runnable类型实例放入到workQueue中了,所以这里可以从workQueue中获取到。
发表评论
-
Hive自定义UDAF详解
2014-07-25 14:14 14628遇到一个Hive ... -
编译libhdfs
2014-02-25 15:32 3718Mysql Applier是Mysql向hdf ... -
Java序列化机制对同一对象的处理
2012-04-20 18:47 0以下例子参考http://developer. ... -
Java的补码表示
2012-04-20 17:19 3827最近发现一个比较低级的问题,就是java中的数 ... -
同步锁的失败可能
2012-04-20 10:29 1039以下例子参考http://developer.51cto.co ... -
SpringExt 扩展原理
2011-07-25 11:27 8945这篇文章是基于webx框架官方文档整理的。具体 ... -
优化多线程执行效率
2011-05-22 21:38 1663摘抄自http://zhmocean.itey ... -
java深度历险
2011-04-17 20:57 1224InfoQ上面有几篇文章不错,适合已经对jav ... -
Java引用类型
2011-04-05 19:00 5430Java有四种引 ... -
double类型运算精度丢失
2011-04-04 15:45 5584前段时间看了一点python入门,写了几个运算 ... -
Java变量初始化
2011-03-29 15:01 1427先看一个例子: public class Te ... -
Java实现循环移位
2011-03-25 20:56 5904做MD5算法时遇到了循环移位,在网上找了写资料 ... -
Java简记
2011-03-18 20:17 1771这里随手做一些记录,以便有空时整理。 ... -
Java的栈和堆
2011-03-12 21:18 1292学的越多, ... -
String的一点东西
2011-03-12 20:24 988关于String类的一点东西,算是对容易疏忽的 ... -
Html转换为PDF
2011-03-11 13:37 26511、html文件转为xhtml文件 ... -
Understand the Serializable and serialVersionUID
2011-03-08 12:54 1496看了一篇简单介绍serialVersionUI ... -
Overriding and Hiding Methods
2011-03-05 16:18 1619方法的override体现在实例方法(inst ... -
Java的参数传递
2011-03-02 16:32 1180关于java参数传递这个问题,伴随着java的 ... -
Java引用类型
2011-02-01 22:58 1036摘自http://www.infoq.com/ ...
相关推荐
主要介绍了java 中Executor, ExecutorService 和 Executors 间的不同的相关资料,需要的朋友可以参考下
NULL 博文链接:https://x125858805.iteye.com/blog/2191873
Executors: 是java.util.concurrent包下的一个类,提供了若干个静态方法,用于生成不同类型的线程池。Executors一共可以创建下面这四类线程池: 1.newFixedThreadPool创建一个可缓存线程池,如果线程池长度超过...
如果 Future 结果没有完成,调用 get() 方法,程序会 阻塞 在那里,直至获取返回结果 先来看第一种实现方式,假设任务 A 由于参数原因,执行时间相对任务 B,C,D 都要长很多,但是按照程序的执行顺序,程序在 get()...
java Executors 使用实例 concurrent.ExecutorService
ExecutorService方法案例文件.zip
接口 java.util.concurrent.ExecutorService 表述了异步执行的机制,并且可以让任务在后台执行。壹個 ExecutorService 实例因此特别像壹個线程池。事实上,在 java.util.concurrent 包中的 ExecutorService 的实现...
ExecutorService的execute和submit方法
Executor: 一个接口,其定义了一个接收Runnable对象的方法executor,其方法签名为executor(Runnable command),该方法接收一个Runable实例,它用来执行一个任务,任务即一个实现了Runnable接口的类,一般来说,...
本程序实现了ExecutorService线程池,内置说明txt说明,可以参考
今天小编就为大家分享一篇关于在spring boot中使用java线程池ExecutorService的讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
集合源码分析 Java8特性 [TOC] 1. Lambda 表达式 与传统匿名内部类写法的对比 无返回值 // 传统写法 new Thread(new Runnable() { @Override public void run() { System.out.println("worker thread is running"); ...
主要介绍了详解JDK中ExecutorService与Callable和Future对线程的支持的相关资料,希望通过本文能帮助到大家,需要的朋友可以参考下
ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());项目中支持将本地路径中的html文件批量转换为PDF,放入本地文件系统中。使用说明List htmlsPaths = ...
运用JAVA的concurrent.ExecutorService线程池实现socket的TCP和UDP连接
主要为大家详细介绍了java ExecutorService使用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
使用 ExecutorService 多线程处理某个进程的简单示例。
2_ExecutorService源码阅读1
NULL 博文链接:https://songjianyong.iteye.com/blog/2056990
主要介绍了Java使用ExecutorService来停止线程服务,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧