- 浏览: 477714 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
白天看黑夜:
PDMReader实现pdm建模快速导出word,html文件 ...
powerDesigner PDM格式导出常见问题 -
小黄牛:
分布一个Dubbo分布式架构项目实战参考内容:http://w ...
dubbo学习 -
Emotion_小寳:
无意中看见了,给悦神赞一个!
openResty安装 -
bewithme:
zy116494718 写道bewithme 写道Ffmpeg ...
ffmpeg实例 -
zy116494718:
bewithme 写道Ffmpeg 这个类哪里来的?楼主你偷来 ...
ffmpeg实例
线程池的作用:
线程池作用就是限制系统中执行线程的数量。
根据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果;少了浪费了系统资源,多了造成系统拥挤效率不高。用线程池控制线程数量,其他线程
排队等候。一个任务执行完毕,再从队列的中取最前面的任务开始执行。若队列中没有等待进程,线程池的这一资源处于等待。当一个新任务需要运行时,如果线程
池中有等待的工作线程,就可以开始运行了;否则进入等待队列。
为什么要用线程池:
- 减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务
- 可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为因为消耗过多的内存,而把服务器累趴下(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机)
ThreadGroup与ThreadPoolExecutor的区别
我自己的理解也是一直以为ThreadGroup就是ThreadPoolExecutor(线程池),这是一个非常大的误会,最近把两者仔细分析了下。 线程组表示一个线程的集合。此外,线程组也可以包含其他线程组。线程组构成一棵树,在树中,除了初始线程组外,每个线程组都有一个父线程组。允许线程访问 有关自己的线程组的信息,但是不允许它访问有关其线程组的父线程组或其他任何线程组的信息;线程消耗包括内存和其它系统资源在内的大量资源。除了 Thread 对象所需的内存之外,每个线程都需要两个可能很大的执行调用堆栈。除此以外,JVM 可能会为每个 Java 线程创建一个本机线程,这些本机线程将消耗额外的系统资源。最后,虽然线程之间切换的调度开销很小,但如果有很多线程,环境切换也可能严重地影响程序的性 能。线程池是因为线程的生成关闭很浪费资源 所以不要频繁的操作 线程次 就是管理线程的地方 不用了它可以让它休眠也就是他替你管理线程 而且比你管理的要好的多。线程池为线程生命周期开销问题和资源不足问题提供了解决方案。通过对多个任务重用线程,线程创建的开销被分摊到了多个任务上。其 好处是,因为在请求到达时线程已经存在,所以无意中也消除了线程创建所带来的延迟。这样,就可以立即为请求服务,使应用程序响应更快。而且,通过适当地调 整线程池中的线程数目,也就是当请求的数目超过某个阈值时,就强制其它任何新到的请求一直等待,直到获得一个线程来处理为止,从而可以防止资源不足。
Executor详解:
Java里面线程池的顶级接口是Executor,但是严格意义上讲Executor并不是一个线程池,而只是一个执行线程的工具。真正的线程池接口是ExecutorService。ThreadPoolExecutor是Executors类的底层实现。我们先介绍下Executors。
Sun在Java5中,对Java线程的类库做了大量的扩展,其中线程池就是Java5的新特征之一,除了线程池之外,还有很多多线程相关的内容,为多线程的编程带来了极大便利。为了编写高效稳定可靠的多线程程序,线程部分的新增内容显得尤为重要。
有关Java5线程新特征的内容全部在java.util.concurrent下面,里面包含数目众多的接口和类,熟悉这部分API特征是一项艰难的学习过程。目前有关这方面的资料和书籍都少之又少,大所属介绍线程方面书籍还停留在java5之前的知识层面上。
当然新特征对做多线程程序没有必须的关系,在java5之前通用可以写出很优秀的多线程程序。只是代价不一样而已。
线程池的基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理。当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程对象所带来的性能开销,节省了系统的资源。
在Java5之前,要实现一个线程池是相当有难度的,现在Java5为我们做好了一切,我们只需要按照提供的API来使用,即可享受线程池带来的极大便利。
Java5的线程池分好多种:固定尺寸的线程池、可变尺寸连接池。
在使用线程池之前,必须知道如何去创建一个线程池,在Java5中,需要了解的是java.util.concurrent.Executors类的API,这个类提供大量创建连接池的静态方法,是必须掌握的。
实例:
一、固定大小的线程池
import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; /** * Java线程:线程池- * * @author Administrator 2009-11-4 23:30:44 */ public class Test { public static void main(String[] args) { //创建一个可重用固定线程数的线程池 ExecutorService pool = Executors.newFixedThreadPool(2); //创建实现了Runnable接口对象,Thread对象当然也实现了Runnable接口 Thread t1 = new MyThread(); Thread t2 = new MyThread(); Thread t3 = new MyThread(); Thread t4 = new MyThread(); Thread t5 = new MyThread(); //将线程放入池中进行执行 pool.execute(t1); pool.execute(t2); pool.execute(t3); pool.execute(t4); pool.execute(t5); //关闭线程池 pool.shutdown(); } } class MyThread extends Thread{ @Override public void run() { System.out.println(Thread.currentThread().getName()+"正在执行。。。"); } }
pool-1-thread-1正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-2正在执行。。。
Process finished with exit code 0
二、单任务线程池
在上例的基础上改一行创建pool对象的代码为:
//创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程。
ExecutorService pool = Executors.newSingleThreadExecutor();
输出结果为:
pool-1-thread-1正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-1正在执行。。。
Process finished with exit code 0
对于以上两种连接池,大小都是固定的,当要加入的池的线程(或者任务)超过池最大尺寸时候,则入此线程池需要排队等待。
一旦池中有线程完毕,则排队等待的某个线程会入池执行。
三、可变尺寸的线程池
与上面的类似,只是改动下pool的创建方式:
//创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。
ExecutorService pool = Executors.newCachedThreadPool();
pool-1-thread-5正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-4正在执行。。。
pool-1-thread-3正在执行。。。
pool-1-thread-2正在执行。。。
Process finished with exit code 0
四、延迟连接池
import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** * Java线程:线程池- * * @author Administrator 2009-11-4 23:30:44 */ public class Test { public static void main(String[] args) { //创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。 ScheduledExecutorService pool = Executors.newScheduledThreadPool(2); //创建实现了Runnable接口对象,Thread对象当然也实现了Runnable接口 Thread t1 = new MyThread(); Thread t2 = new MyThread(); Thread t3 = new MyThread(); Thread t4 = new MyThread(); Thread t5 = new MyThread(); //将线程放入池中进行执行 pool.execute(t1); pool.execute(t2); pool.execute(t3); //使用延迟执行风格的方法 pool.schedule(t4, 10, TimeUnit.MILLISECONDS); pool.schedule(t5, 10, TimeUnit.MILLISECONDS); //关闭线程池 pool.shutdown(); } } class MyThread extends Thread { @Override public void run() { System.out.println(Thread.currentThread().getName() + "正在执行。。。"); } }
pool-1-thread-1正在执行。。。
pool-1-thread-2正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-2正在执行。。。
Process finished with exit code 0
五、单任务延迟连接池
在四代码基础上,做改动
//创建一个单线程执行程序,它可安排在给定延迟后运行命令或者定期地执行。
ScheduledExecutorService pool = Executors.newSingleThreadScheduledExecutor();
pool-1-thread-1正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-1正在执行。。。
Process finished with exit code 0
六、自定义线程池
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; /** * Java线程:线程池-自定义线程池 * * @author Administrator 2009-11-4 23:30:44 */ public class Test { public static void main(String[] args) { //创建等待队列 BlockingQueue bqueue = new ArrayBlockingQueue(20); //创建一个单线程执行程序,它可安排在给定延迟后运行命令或者定期地执行。 ThreadPoolExecutor pool = new ThreadPoolExecutor(2,3,2,TimeUnit.MILLISECONDS,bqueue); //创建实现了Runnable接口对象,Thread对象当然也实现了Runnable接口 Thread t1 = new MyThread(); Thread t2 = new MyThread(); Thread t3 = new MyThread(); Thread t4 = new MyThread(); Thread t5 = new MyThread(); Thread t6 = new MyThread(); Thread t7 = new MyThread(); //将线程放入池中进行执行 pool.execute(t1); pool.execute(t2); pool.execute(t3); pool.execute(t4); pool.execute(t5); pool.execute(t6); pool.execute(t7); //关闭线程池 pool.shutdown(); } } class MyThread extends Thread { @Override public void run() { System.out.println(Thread.currentThread().getName() + "正在执行。。。"); try { Thread.sleep(100L); } catch (InterruptedException e) { e.printStackTrace(); } } }
pool-1-thread-1正在执行。。。
pool-1-thread-2正在执行。。。
pool-1-thread-2正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-2正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-2正在执行。。。
Process finished with exit code 0
创建自定义线程池的构造方法很多,本例中参数的含义如下:
ThreadPoolExecutor
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue)
用给定的初始参数和默认的线程工厂及处理程序创建新的 ThreadPoolExecutor。使用 Executors 工厂方法之一比使用此通用构造方法方便得多。
参数:
corePoolSize - 池中所保存的线程数,包括空闲线程。
maximumPoolSize - 池中允许的最大线程数。
keepAliveTime - 当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间。
unit - keepAliveTime 参数的时间单位。
workQueue - 执行前用于保持任务的队列。此队列仅保持由 execute 方法提交的 Runnable 任务。
抛出:
IllegalArgumentException - 如果 corePoolSize 或 keepAliveTime 小于零,或者 maximumPoolSize 小于或等于零,或者 corePoolSize 大于 maximumPoolSize。
NullPointerException - 如果 workQueue 为 null
自定义连接池稍微麻烦些,不过通过创建的ThreadPoolExecutor线程池对象,可以获取到当前线程池的尺寸、正在执行任务的线程数、工作队列等等。
发表评论
-
Future详解
2021-08-10 11:37 341一般使用线程池执行任务都是调用的execute方法,这个方法 ... -
CountDownLanch原理
2021-08-09 20:00 284文章转载自:https://segmentfault.com/ ... -
Java基础之Java8中Map的compute的使用
2020-10-10 18:57 1349假如我们现在有一需求,需要统计一个字符串中各个字母出现的频 ... -
java泛型实例
2019-06-15 21:09 839首先定义一个接口 ... -
Java 7 新的 try-with-resources 语句,自动资源释放
2019-04-25 14:41 474转载请注明出处:https ... -
java字节流与字符流的区别
2016-10-26 18:34 1277字节流与字符流 先来看一下流的概念: 在程序中所有的数 ... -
视频库之断点下载
2015-08-10 16:33 582断点续传主要是使用http协议中range的属性来取得资源的 ... -
视频库之断点续传
2015-07-30 11:37 1204近日公司有个项目要做一个视频库,故开始阶段 ... -
视频库之断点续传
2015-07-29 18:07 6近日公司有个项目要做一个视频库,故开始阶段性 ... -
数据库读写分离(java部分配置)
2015-06-15 15:26 2585假设有两台数据库服务器:192.168.0.1(写) 和1 ... -
图片压缩
2014-10-21 14:53 892下面方法可以做到压缩图片不失真: public c ... -
java图片合成
2013-11-05 16:52 2943下面这个例子介绍如何把3张图片合在一张图片里,用的是jav ... -
文件上传与下载
2013-01-16 10:03 1480文件下载: jsp: <input type=& ... -
线程池系列三:结合线程池实现Socket
2012-11-14 17:26 1453Java5增加了新的类库并发集java.util.concur ... -
线程池系列二:ThreadPoolExecutor讲解
2012-11-14 11:42 1582一、简介 1)线程池 ... -
ArrayList 和 CopyOnWriteArrayList 线程安全测试
2012-10-19 17:48 1934ArrayList 是 非线程安全的, CopyOnWrite ... -
后台json传递
2012-06-21 15:38 4085json除了可以用于前台传递,还可用于后台之间传递。它可以传递 ... -
解决中文乱码问题
2012-05-18 14:42 2962首先可以试下在TOMCAT中 ... -
HttpClient应用
2012-05-11 17:15 1564用HttpClient爬网站时有时会遇到一种现象,就是自己写个 ... -
cookie的读取与写入
2012-05-11 11:42 954java对cookie的操作比较简单,主要介绍下建立cooki ...
相关推荐
- **创建线程池**:通过`ExecutorService`接口实例化,如`Executors`类提供的`newFixedThreadPool`、`newCachedThreadPool`等静态方法。 - **提交任务**:使用`ExecutorService`的`execute()`方法提交`Runnable`或...
Socket线程池是一种高效管理网络连接的技术,它结合了Socket通信和线程池的设计思想,以提高系统的并发处理能力和资源利用率。在Java等编程语言中,我们常常利用线程池来处理大量的并发Socket连接,避免频繁创建和...
3.可重用固定个数的线程池(Executors.newFixedThreadPool(int n)):创建一个可重用固定个数的线程池,以共享的无界队列方式来运行这些线程。 4._SCHEDULED线程池(Executors.newScheduledThreadPool(int ...
你可以使用`Executors`工具类的静态方法来创建线程池,例如`newFixedThreadPool(int nThreads)`,它会创建一个固定大小的线程池,当有新连接请求时,线程池中的空闲线程会处理这个请求,如果所有线程都在忙碌,新...
3. **SynchronousQueue**:一个特殊的阻塞队列,它不存储元素,每个put操作必须等待一个take操作,反之亦然。SynchronousQueue提供了公平锁和非公平锁的选项,适用于需要精确控制线程间通信的场景。 以下是一些常用...
常用的接口有`Executors`,可以创建固定大小、单线程、定时任务等类型的线程池。 7. **死锁与活锁**:当两个或更多线程互相等待对方释放资源而无法继续执行时,就会发生死锁。活锁则是线程虽然没有阻塞,但由于某种...
1. 创建线程池:使用`Executors`静态工厂方法创建一个固定大小的线程池,如`ExecutorService executor = Executors.newFixedThreadPool(poolSize);` 2. 实现图片下载接口:定义一个接口,包含下载图片的方法,如`...
本篇将详细讲解如何实现Android中的异步图像加载,包括使用线程池和缓存策略。 首先,我们需要理解为什么需要异步加载。在Android中,主线程负责UI更新,如果在主线程中执行耗时操作(如网络请求或解码图片),会...
本篇将对Android中的异步图像加载进行详细讲解,包括线程池的使用和缓存方法。 1. **异步加载图像的重要性** - 在Android中,主线程负责更新UI,如果在主线程中执行耗时操作(如网络请求或图片解码),会导致应用...
本篇文章将详细讲解如何在Android环境下实现SOAP线程池并发请求,以提高应用性能和用户体验。 一、SOAP基础 SOAP是基于XML的协议,它允许服务提供商和消费者通过HTTP、SMTP等传输协议进行通信。在Android中,我们...
例如,可以使用`Executors.newFixedThreadPool(int corePoolSize)`创建固定大小的线程池。 3. **分配下载任务**:将文件分成若干个块,每个块对应一个线程进行下载。块的大小应该根据文件大小和网络状况来调整,以...
2. **线程池**:Executor框架是JUC的核心,它提供ThreadPoolExecutor和Executors类来创建和管理线程池。线程池可以有效地重用已存在的线程,减少创建和销毁线程的开销,提高系统性能。 3. **并发工具类**:如...
本文将详细讲解ExecutorService的原理、使用场景以及如何通过Executors类创建线程池。 1. 为什么使用线程池 线程池的主要目的是为了优化线程的生命周期管理。在处理大量并发任务时,如果每个任务都单独创建线程,...
- `Executors`:提供创建线程池的静态工厂方法。 6. **并发工具类**: - `CountDownLatch`:用于多线程同步,计数器减至零后所有线程继续执行。 - `CyclicBarrier`:多线程到达屏障后一起继续,可重用。 - `...
6. **线程池**:深入讨论`ExecutorService`、`ThreadPoolExecutor`和`Executors`,如何配置线程池,以及它们在管理线程资源上的优势。 7. **线程优先级**:理解线程优先级的概念,以及`setPriority()`方法的使用。 ...
- **线程池**:ExecutorService、ThreadPoolExecutor和Executors的使用,以及线程池的参数调整。 7. **网络编程** - **套接字编程**:Socket和ServerSocket的使用,以及TCP和UDP的区别。 - **HTTP通信**:利用...
本资源“后端开发-06-线程执行带有参数的任务.ev4.rar”可能是一个教学视频或课程,专注于讲解如何在后端程序中使用线程来处理具有输入参数的任务。下面将详细探讨这个主题。 1. **线程基础** - **线程概念**:...
在实际开发中,Java的Executor框架提供了多种预定义的线程池,如`Executors.newFixedThreadPool`用于创建固定大小的线程池,`Executors.newSingleThreadExecutor`创建只有一个线程的线程池,以及`Executors....
- **Executors**:提供预定义的线程池,如newFixedThreadPool, newSingleThreadExecutor等。 8. **Demo分析**: 这个示例可能包含以上各种多线程技术的实践,通过阅读源码,我们可以了解如何在Android中实际运用...