Java线程池
2016-03-04 11:32
477 查看
我们平时在写程序中常常使用多线程来提高CPU以及其他资源的利用率,但是当CPU中的线程超过了CPU调度范围时,我们的程序就会变得缓慢甚至出现死锁 导致程序卡死等现象。也有很多时候我们需要创建的线程量巨大,但是每个线程的执行时间却相对较小,这样在新启线程和关闭线程的时候消耗的系统资源要比花在处理实际的用户请求的时间和资源更多。除了创建和销毁线程的开销之外,活动的线程也消耗系统资源。在一个JVM
里创建太多的线程可能会导致系统由于过度消耗内存而用完内存或“切换过度”。
线程池的出现能较好的解决以上问题,线程池为线程生命周期开销问题和资源不足问题提供了解决方案。通过对多个任务重用线程,线程创建的开销被分摊到了多个 任务上。其好处是,因为在请求到达时线程已经存在,所以无意中也消除了线程创建所带来的延迟。这样,就可以立即为请求服务,使应用程序响应更快。而且,通 过适当地调整线程池中的线程数目,也就是当请求的数目超过某个阈值时,就强制其它任何新到的请求一直等待,直到获得一个线程来处理为止,从而可以防止资源
不足。
在使用线程池之前,必须知道如何去创建一个线程池,在Java5中,需要了解的是java.util.concurrent.Executors类的API,这个类提供了四种比较常用线程池。
运行结果:
pool-1-thread-3 is running...
pool-1-thread-4 is running...
pool-1-thread-2 is running...
pool-1-thread-1 is running...
pool-1-thread-5 is running...
此时线程池的最大线程为3,运行效果:
pool-1-thread-1 is running...
pool-1-thread-2 is running...
pool-1-thread-2 is running...
pool-1-thread-1 is running...
pool-1-thread-3 is running...
最多只能运行两个2个线程,延迟效果自行体会,运行结果:
pool-1-thread-1 is running...
pool-1-thread-2 is running...
pool-1-thread-1 is running...
只会运行一个线程,运行效果:
pool-1-thread-1 is running...
pool-1-thread-1 is running...
pool-1-thread-1 is running...
pool-1-thread-1 is running...
pool-1-thread-1 is running...
以上四中线程池分别运用于不同场景,可在项目中根据实际情况选择应用,线程池的作用不仅仅是可控制创建线程的数量,更多的是在多线程中省去了频繁的线程创建和销毁过程,降低了系统销毁。
里创建太多的线程可能会导致系统由于过度消耗内存而用完内存或“切换过度”。
线程池的出现能较好的解决以上问题,线程池为线程生命周期开销问题和资源不足问题提供了解决方案。通过对多个任务重用线程,线程创建的开销被分摊到了多个 任务上。其好处是,因为在请求到达时线程已经存在,所以无意中也消除了线程创建所带来的延迟。这样,就可以立即为请求服务,使应用程序响应更快。而且,通 过适当地调整线程池中的线程数目,也就是当请求的数目超过某个阈值时,就强制其它任何新到的请求一直等待,直到获得一个线程来处理为止,从而可以防止资源
不足。
在使用线程池之前,必须知道如何去创建一个线程池,在Java5中,需要了解的是java.util.concurrent.Executors类的API,这个类提供了四种比较常用线程池。
1.newCachedThreadPool
newCachedThreadPool()是根据需求创建新线程的,需求多时,创建的就多,需求少时,JVM自己会慢慢的释放掉多余的线程,它是一种可变尺寸的线程池。ExecutorService threadPool = Executors.newCachedThreadPool(); for(int i=0;i<5;i++){ MyThread t = new MyThread(); threadPool.execute(t); }
运行结果:
pool-1-thread-3 is running...
pool-1-thread-4 is running...
pool-1-thread-2 is running...
pool-1-thread-1 is running...
pool-1-thread-5 is running...
2.newFixedThreadPool
创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。新的线程加入后,如果正在运行的线程达到了上限,则会阻塞,直到有了空闲的线程来运行。他是定长尺寸的线程池。ExecutorService threadPool = Executors.newFixedThreadPool(3);
此时线程池的最大线程为3,运行效果:
pool-1-thread-1 is running...
pool-1-thread-2 is running...
pool-1-thread-2 is running...
pool-1-thread-1 is running...
pool-1-thread-3 is running...
3.newScheduledThreadPool
创建一个定长线程池,支持定时及周期性任务执行。延迟执行示例代码如下:ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(2); MyThread t1 = new MyThread(); MyThread t2 = new MyThread(); MyThread t3 = new MyThread(); // 将线程放入池中进行执行 scheduledThreadPool.execute(t1); // 使用延迟执行风格的方法 scheduledThreadPool.schedule(t2, 1000, TimeUnit.MILLISECONDS); scheduledThreadPool.schedule(t3, 10, TimeUnit.MILLISECONDS);
最多只能运行两个2个线程,延迟效果自行体会,运行结果:
pool-1-thread-1 is running...
pool-1-thread-2 is running...
pool-1-thread-1 is running...
4.newSingleThreadExecutor
创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。示例代码如下:ExecutorService threadPool = Executors.newSingleThreadExecutor();
只会运行一个线程,运行效果:
pool-1-thread-1 is running...
pool-1-thread-1 is running...
pool-1-thread-1 is running...
pool-1-thread-1 is running...
pool-1-thread-1 is running...
以上四中线程池分别运用于不同场景,可在项目中根据实际情况选择应用,线程池的作用不仅仅是可控制创建线程的数量,更多的是在多线程中省去了频繁的线程创建和销毁过程,降低了系统销毁。
相关文章推荐
- java学习笔记-文件和目录
- JavaBean之简单应用JSP页面
- Java8 HashMap的实现原理分析
- ORM--------Hibernate、Mybatis与Spring Data的区别
- Java单例模式深入详解
- Eclipse插件开发之ActionSet分割符
- [转]MyEclipse8.5破解方法
- Java线程Dump分析工具--jstack
- Java复习笔记(一)——Java的运行机制
- springmvc-- Failed to convert property value of type 'java.lang.String' to required type
- java Jackson 库操作 json 的基本演示
- 【leetcode】【110】Balanced Binary Tree
- java反射机制笔记
- java聊天源码 java后台框架源码 websocket源码 IM
- 出现java heap space的问题(内存溢出)
- Myeclipse如何自动创建hibernate
- Web应用web.xml的Struts2的配置
- 【leetcode】【108】Convert Sorted Array to Binary Search Tree
- Java 虚拟机体系结构
- 国际化: 理解Java平台下的Locale