您的位置:首页 > 编程语言 > Java开发

java线程池newFixedThreadPool详解

2016-04-10 23:48 531 查看
java线程池Executors.newFixedThreadPool(int nThread)很多人都用过,但可能不一定看过里面的实现,这几天刚好去面试,这个东西基本也就是个必问题了,这下顺便整理一下,至于面试的结果,先就按下不表了。
使用方法


ExecutorService service = Executors.newFixedThreadPool(3);
for (int i = 0 ; i < 4 ;i ++) {
int  j = i;
service.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(10000);
System.out.println("test" + j);
} catch (Exception e) {
}

}
});
}


newFixedThreadPool(int nThread)必须指定线程池的大小,线程池没有默认值,而newCachedThreadPool()是不需要设置线程池大小,默认就是Integer.MAX。

newFixedThreadPool()用的是LinkedBlockingQueue,但由于newFixedThreadPool()是必须设置线程池大小的,所以LinkedBlockingQueue是有界的。

其实newFixedThreadPool()在严格上说并不会复用线程,每运行一个Runnable都会通过ThreadFactory创建一个线程。

ThreadPoolExecutor.execute(Runnable command)

int c = ctl.get();
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);


如果正在执行中的线程大于线程池的大小,就会执行上述代码,把Runnable放入wokrQueuue,就是LinkBlockingQueue。

ThreadPoolExecutor.getTask()

try {
Runnable r = timed ? workQueue.poll(keepAliveTime,TimeUnit.NANOSECONDS) :
workQueue.take();
if (r != null)
return r;
timedOut = true;
} catch (InterruptedException retry) {
timedOut = false;
}


取出Runnable,执行线程。

以后会再谈一下Woker的使用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: