java Executors 线程池解读
来源:互联网 发布:ionic lab for mac 编辑:程序博客网 时间:2024/06/05 06:24
1.不变的java线程新建及启动方式
public class TestThread implements Runnable{
public void run(){
//out("hello..")
}
}
Thread thread = new Thread(TestThread);
thread.start();
2.Executors 以池的方式如何管理和启动线程?
以newFixedThreadPool方法为例,ExecutorService 具体对象为
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
参数含义及使用方式,代码如下:
if (workerCountOf(c) < corePoolSize) { if (addWorker(command, true)) return; c = ctl.get(); } if (isRunning(c) && workQueue.offer(command)) { int recheck = ctl.get(); if (! isRunning(recheck) && remove(command)) reject(command); else if (workerCountOf(recheck) == 0) addWorker(null, false); } else if (!addWorker(command, false)) reject(command);
解释:先用coreSize,满了后,用queue,queue再满,用maxSize,再满,那就reject
一般情况下ThreadFactory 以及 RejectedExecutionHandler 使用默认(也可自由实现)
默认ThreadFactory 如下:
static class DefaultThreadFactory implements ThreadFactory { private static final AtomicInteger poolNumber = new AtomicInteger(1); private final ThreadGroup group; private final AtomicInteger threadNumber = new AtomicInteger(1); private final String namePrefix; DefaultThreadFactory() { SecurityManager s = System.getSecurityManager(); group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup(); namePrefix = "pool-" + poolNumber.getAndIncrement() + "-thread-"; } 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; } }
这里包括了线程名字的命名,以及线程池所用线程对象(new Thread)的创建。
3. submit 做了什么?
先看下这个类
public abstract class AbstractExecutorService implements ExecutorService方法包括
public Future<?> submit(Runnable task) { if (task == null) throw new NullPointerException(); RunnableFuture<Void> ftask = newTaskFor(task, null); execute(ftask); return ftask; }以及
public <T> Future<T> submit(Callable<T> task) { if (task == null) throw new NullPointerException(); RunnableFuture<T> ftask = newTaskFor(task); execute(ftask); return ftask; }
不管submit的是Runnable还是Callable,都会转化为FutureTask的对象
其中的两个重要字段
/** The underlying callable; nulled out after running */ private Callable<V> callable; /** The result to return or exception to throw from get() */ private Object outcome; // non-volatile, protected by state reads/writes
用callable存放submit的Runnable或者Callable
再看FutureTask实现的两个接口Runnable, Future
其中,run方法的实现如下:
try { result = c.call(); ran = true; } catch (Throwable ex) { result = null; ran = false; setException(ex); } if (ran) set(result);
重点是,调用了Callable中的call方法,以及set(result),把结果放入outcome中。通过FutureTask的get()操作,获得左后的outcome结果。
4.回过头来,看下线程是如何start()的
当小于池的coreSize时,在类ThreadPoolExecutor的方法addWorker(Runnable firstTask, boolean core)中,重点代码如下:
final Thread t = w.thread; if (t != null) { final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { // Recheck while holding lock. // Back out on ThreadFactory failure or if // shut down before lock acquired. int rs = runStateOf(ctl.get()); if (rs < SHUTDOWN || (rs == SHUTDOWN && firstTask == null)) { if (t.isAlive()) // precheck that t is startable throw new IllegalThreadStateException(); workers.add(w); int s = workers.size(); if (s > largestPoolSize) largestPoolSize = s; workerAdded = true; } } finally { mainLock.unlock(); } if (workerAdded) { t.start(); workerStarted = true; } }
其中,t 对象就是上面DefaultThreadFactory创建出来的线程,看后面的代码,执行了 t.start();
还有一处需要关注的是workers.add(w),这里就是池维护的线程集合,workers 是HastSet类型。
5.总结下
(1)DefaultThreadFactory用于创建真正执行的线程
(2)ThreadPoolExecutor用于维护池及队列、执行线程等
(3)FutureTask 是池中线程执行的最终任务(也就是实现Runnable的类),它还有另一个职责,就是存储、返回了 .get()的结果
(4)用户自己创建的TestThread ,不管是Runnable还是Callable,最终都被转为Callable,并在FutureTask 的run方法中执行了 .call() 方法
6.欢迎指正错误,我也会不断补充。
- java Executors 线程池解读
- Java Executors(线程池)
- java Executors(线程池)
- Java Executors(线程池)
- Java Executors(线程池)
- Executors线程池--java
- Java Executors(线程池)
- java Executors线程池
- Java线程池Executors
- Java Executors(线程池)
- Java Executors(线程池)
- Java Executors(线程池)
- Java Executors(线程池)
- Java Executors(线程池)
- Java Executors(线程池)
- Java Executors(线程池)
- Java Executors(线程池)
- Java Executors(线程池)
- 专访海尔小帅影院创始人马文俊:硬件不是未来 需求才是未来
- window.location.href和window.top.location.href的区别
- 在JDBC一次插入多个表、多条记录
- hdu 1051 Wooden Sticks
- 外部类.this.成员域
- java Executors 线程池解读
- mysql--查看mysql状态的常用命令
- AlexNet解析
- bzoj 2423: [HAOI2010]最长公共子序列 (DP)
- 第四章 使用OpenCV探测来至运动的结构——Chapter 4:Exploring Structure from Motion Using OpenCV 标签: SFM3D重建 2015-01-15
- SAS导入csv文件乱码解决办法
- [HDU-5980] [Problem J]水题
- Python-学习笔记(一)
- 共享内存