- 浏览: 62410 次
- 性别:
- 来自: 成都
文章分类
最新评论
简单介绍一下java Executors框架来管理线程池原理:
1、线程池中的线程如何创建?创建后保存在哪里?
线程池中的每个线程封装在workder中,然后保存在一个HashMap<Workder>中。
2、当任务多于线程的时候怎么执行?例如有5个任务但是只有只创建了3个线程。
看Worker中的run方法调用的是runWorker方法:
很显然这是生产者消费者模式的体现。runWorker循环阻塞等待从workQueue中取出任务。然后执行。
总结线程池原理:
线程池在执行线程的时候创建线程。然后执行完的线程并没有立即销毁而是阻塞等待 workQueue中来新任务然后接着执行。线程池也是生产者消费者模式的体现。
//创建一个线程数大小为3的线程池 Executors.newFixedThreadPool(3);
1、线程池中的线程如何创建?创建后保存在哪里?
public class ThreadPoolExecutor extends AbstractExecutorService { //用队列保存需要执行的任务 private final BlockingQueue<Runnable> workQueue; //将Worker保存在HashSet中,Worker是什么? private final HashSet<Worker> workers = new HashSet<Worker>(); //Worker包装了Runnable private final class Worker extends AbstractQueuedSynchronizer implements Runnable { private static final long serialVersionUID = 6138294804551838833L; Worker(Runnable firstTask) { setState(-1); // inhibit interrupts until runWorker this.firstTask = firstTask; this.thread = getThreadFactory().newThread(this); } public void run() { runWorker(this); } //看execute方法 public void execute(Runnable command) { if (command == null) throw new NullPointerException(); int c = ctl.get(); if (workerCountOf(c) < corePoolSize) { //重点来了,addWorker.好了这就是线程保存在哪里。 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); } //addWorker源码 private boolean addWorker(Runnable firstTask, boolean core) { retry: for (;;) { int c = ctl.get(); int rs = runStateOf(c); // Check if queue empty only if necessary. if (rs >= SHUTDOWN && ! (rs == SHUTDOWN && firstTask == null && ! workQueue.isEmpty())) return false; for (;;) { int wc = workerCountOf(c); if (wc >= CAPACITY || wc >= (core ? corePoolSize : maximumPoolSize)) return false; if (compareAndIncrementWorkerCount(c)) break retry; c = ctl.get(); // Re-read ctl if (runStateOf(c) != rs) continue retry; // else CAS failed due to workerCount change; retry inner loop } } boolean workerStarted = false; boolean workerAdded = false; Worker w = null; try { final ReentrantLock mainLock = this.mainLock; w = new Worker(firstTask); final Thread t = w.thread; if (t != null) { mainLock.lock(); try { int c = ctl.get(); int rs = runStateOf(c); 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; } } } finally { if (! workerStarted) addWorkerFailed(w); } return workerStarted; }
线程池中的每个线程封装在workder中,然后保存在一个HashMap<Workder>中。
2、当任务多于线程的时候怎么执行?例如有5个任务但是只有只创建了3个线程。
看Worker中的run方法调用的是runWorker方法:
final void runWorker(Worker w) { Thread wt = Thread.currentThread(); Runnable task = w.firstTask; w.firstTask = null; w.unlock(); // allow interrupts boolean completedAbruptly = true; try { //循环获取Runnable,getTask()方法从workQueue中获取任务 while (task != null || (task = getTask()) != null) { w.lock(); if ((runStateAtLeast(ctl.get(), STOP) || (Thread.interrupted() && runStateAtLeast(ctl.get(), STOP))) && !wt.isInterrupted()) wt.interrupt(); try { beforeExecute(wt, task); Throwable thrown = null; try { task.run(); } catch (RuntimeException x) { thrown = x; throw x; } catch (Error x) { thrown = x; throw x; } catch (Throwable x) { thrown = x; throw new Error(x); } finally { afterExecute(task, thrown); } } finally { task = null; w.completedTasks++; w.unlock(); } } completedAbruptly = false; } finally { processWorkerExit(w, completedAbruptly); } }
很显然这是生产者消费者模式的体现。runWorker循环阻塞等待从workQueue中取出任务。然后执行。
总结线程池原理:
线程池在执行线程的时候创建线程。然后执行完的线程并没有立即销毁而是阻塞等待 workQueue中来新任务然后接着执行。线程池也是生产者消费者模式的体现。
发表评论
-
读ThreadLocal源代码
2017-10-12 15:00 239//可以存取线程局部变量 //先看构造函数 pub ... -
读Exchanger源码
2017-10-10 11:38 328//用于线程间交换数据 public V exchang ... -
读Executors源码
2017-09-29 15:23 258//一个管理线程创建的类里面都是静态方法 //创建一 ... -
读ScheduledThreadPoolExecutor源码
2017-09-25 17:33 408//一个可以延迟执行的定时任务 //先看构造函数 构造函 ... -
读部分ThreadPoolExecutor源码
2017-09-25 15:27 303//线程池 //先看构造方法 public Threa ... -
读AbstractExecutorService
2017-09-23 16:34 320//他是ExecutorService的部分实现 pub ... -
读ExecutorCompletionService源码
2017-09-23 11:22 482//一个用来管理已完成任务的service,内部封装了一个 ... -
读FutureTask源码
2017-09-22 16:45 266//一个可以异步返回计算的结果 //它同时实现了Futu ... -
读ConcurrentSkipListMap源码
2017-09-21 15:11 287//数据结构是跳表 关于数据结构http://blog.c ... -
读Semaphore源码
2017-09-09 14:58 289//一个信号量,只有在池中还拥有许可时才允许线程继续执行。 ... -
读CyclicBarrier源码
2017-09-01 17:59 341//一个循环的屏障。所有的线程在屏障处等待其他线程执行完毕 ... -
读CountDownLatch源码
2017-09-01 14:01 319//在完成一组操作之前允许一个或多个线程等待内部用的AQS ... -
读ConcurrentLinkedQueue
2017-09-01 11:40 284//这是一个无阻塞的队列没有加任何锁全部利用CAS机制实现 ... -
读ConcurrentHashMap源码
2017-08-31 11:21 271//先看构造函数 public ConcurrentHa ... -
读CopyOnWriteArrayList源码
2017-08-22 12:59 404//在该集合上的写操作都是在原有的副本上进行的操作。这样可 ... -
读LinkedBlockingDeque源码
2017-08-21 14:26 553//这是一个支持双端操作的可阻塞队列 //先看构造函数 ... -
读SynchronousQueue源码
2017-08-10 10:51 372//先看构造方法 public SynchronousQ ... -
读PriorityBlocking源码
2017-08-09 13:47 352//一个基于而为堆的优先级队列,它是无界的。 //先看构 ... -
读DelayQueen源码
2017-08-07 15:16 271//一个基于二叉堆优先 ... -
LinkedblockingQueue源码解读
2017-08-04 13:03 345//LinkedBlockQueue //先看构造函数 ...
相关推荐
### JAVA线程池原理及几种线程池类型的详细介绍 #### 一、线程池的引入背景及重要性 在现代软件开发中,特别是在基于Java的应用程序设计中,线程池技术已经成为提高系统性能和资源利用率的关键手段之一。线程池...
Java concurrency线程池之线程池原理(一)_动力节点Java学院整理,动力节点口口相传的Java黄埔军校
Java线程池是一种高效管理线程的工具,它允许开发者预先创建一组线程,并复用它们来处理任务,从而降低了创建和销毁线程的开销。线程池的使用尤其适用于处理大量短小任务的场景,例如Web服务器、数据库服务器等。在...
JAVA线程池原理实例详解 JAVA线程池是java中的一种高效的线程管理机制,它可以控制线程的创建、销毁和复用,从而提高系统的性能和可靠性。下面我们将详细介绍JAVA线程池的原理、创建、使用方法及相关注意事项。 一...
本文将深入探讨Java线程池的原理、封装以及相关知识点。 ### 1. Java线程池概念 Java线程池由`java.util.concurrent`包中的`ExecutorService`接口和其子类实现。其中,最常用的是`ThreadPoolExecutor`类,它提供了...
理解Java线程池的原理和实现,可以帮助我们更有效地管理并发任务,提升系统性能,同时避免资源浪费和线程安全问题。在实际开发中,合理配置线程池参数,结合业务场景选择合适的线程池类型,是优化系统性能的关键步骤...
Java线程池是一种高效利用系统资源、管理并发执行任务的机制。...总的来说,理解Java线程池的工作原理和实现对于优化并发应用程序至关重要,它可以帮助我们更好地控制系统的并发度,提高系统的响应速度和资源利用率。
Java线程池是一种高效管理线程的工具,它允许开发者预先创建一组线程,当需要执行新任务时,线程池会从池中选择一个空闲线程来执行任务,而不是每次都创建新的线程。线程池的使用有助于减少线程创建和销毁的开销,...
本文将深入探讨Java线程池的工作原理,并通过实际代码示例,展示如何高效地使用线程池。 Java线程池是并发编程中的一个重要工具,它通过减少线程创建和销毁的开销,提高了程序的性能和资源利用率。理解线程池的...
### 自定义实现Java线程池 #### 一、概述 在深入探讨自定义Java线程池之前,我们先简要回顾一下线程池的基本概念及其重要性。线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动...
总结Java线程池是Java多线程编程的重要工具,通过合理的配置和使用,可以有效地管理和调度线程,提高系统性能。理解线程池的工作原理和参数配置,对于编写高效、稳定的多线程程序至关重要。在实际应用中,应根据任务...
Java线程池是一种高效管理线程的机制,它允许开发者预先设定线程的数量,并通过池化的方式重用已创建的线程,以提高系统性能,减少线程的创建和销毁开销。线程池在Java中是通过`java.util.concurrent`包下的`...
首先希望大家喜欢我制作的文档,如果文档中有什么误解的地方,望告诉一下,5分是也不多,是系统默认的,那么就5分咯,java多线程详解,线程池原理,8种锁,java内存模型......
Java线程池是一种高效管理线程资源的工具,它通过维护一组可重用的线程来减少创建和销毁线程的开销。在Java中,`java.util.concurrent`包提供了`ExecutorService`接口和它的实现类,如`ThreadPoolExecutor`,来支持...
通过剖析Java中线程池的原理,解读Java线程池源码,并给出线程池调用的示例,帮助理解线程池的基本原理。
Java线程池是一种高效管理并发任务的机制,它允许开发者预先配置一定数量的线程,以便在处理多个并发任务时能有效地复用这些线程,从而避免了频繁创建和销毁线程带来的开销。在Java中,`java.util.concurrent`包下的...
Java线程池是一种高效管理线程资源的技术,它允许开发者创建一组可重用的工作线程,从而避免频繁地创建和销毁线程带来的性能开销。线程池在Java中主要通过`java.util.concurrent`包中的`ExecutorService`接口及其...
本文所提及的基于Java线程池技术的数据爬虫设计与实现,不仅涉及到了数据爬虫的原理和架构,还包括了多线程编程的知识点,以及线程池技术在数据爬虫中的具体应用。 首先,数据爬虫的基本原理是模拟用户的点击行为,...
Java线程池是Java并发编程中的重要组成部分,它允许开发者高效地管理多个并发执行的线程,有效地控制系统的资源消耗,提高系统性能和稳定性。在Java中,`java.util.concurrent`包提供了`ExecutorService`接口及其...
鸟之家破解器源码