java开发中几种常见的线程池
线程池
常用线程池
几种常用的的生成线程池的方法:
newCachedThreadPoolnewFixedThreadPoolnewScheduledThreadPoolnewSingleThreadExecutornewSingleThreadScheduledExecutor
例子:newFixedThreadPool
ExecutorService threadPool = Executors.newFixedThreadPool(3);
for(int i=0;i<10;i++){
threadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
});
}
单线程newSingleThreadExecutor可用于重启
用线程池启动定时器
例子:类似Timer的定时执行
Executors.newScheduledThreadPool(3).scheduleAtFixedRate(
new Runnable() {
@Override
public void run() {
System.out.println("ScheduledThreadPool "+Thread.currentThread().getName());
}
},3,1, TimeUnit.SECONDS
);
Callable&Future
ExecutorService在Executor的基础上增加了一些方法,其中有两个核心的方法:
Future<?> submit(Runnable task)<T> Future<T> submit(Callable<T> task)
这两个方法都是向线程池中提交任务,它们的区别在于Runnable在执行完毕后没有结果,Callable执行完毕后有一个结果。这在多个线程中传递状态和结果是非常有用的。另外他们的相同点在于都返回一个Future对象。Future对象可以阻塞线程直到运行完毕(获取结果,如果有的话),也可以取消任务执行,当然也能够检测任务是否被取消或者是否执行完毕。
Lock&Condition
Lock
Lock功能类似传统多线程技术里的synchronized,实现线程互斥,但更加面向对象。将需要互斥的代码片段放到lock.lock();和lock.unlock();之间。
例子
class A{
private Lock lock = new ReentrantLock();
public void function(){
lock.lock();
try{
//功能代码
}finally{
lock.unlock();
}
}
}
- 读写锁
javaDoc文档读写锁例子,缓存:
class CachedData {
Object data;
volatile boolean cacheValid;
final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
void processCachedData() {
rwl.readLock().lock();
if (!cacheValid) {
// Must release read lock before acquiring write lock
rwl.readLock().unlock();
rwl.writeLock().lock();
try {
// Recheck state because another thread might have
// acquired write lock and changed state before we did.
if (!cacheValid) {
data = ...
cacheValid = true;
}
// Downgrade by acquiring read lock before releasing write lock
rwl.readLock().lock();
} finally {
rwl.writeLock().unlock(); // Unlock write, still hold read
}
}
try {
use(data);
} finally {
rwl.readLock().unlock();
}
}
}
重点注意在释放写锁前加读锁那部分代码,注释为// Downgrade by acquiring read lock before releasing write lock。自己挂了写锁,再挂读锁是可以的,这面涉及的技巧以后再研究。
Condition
Condition类似于传统多线程技术中的Object.wait和Object.notify,实现线程间同步。
javaDoc文档例子,可阻塞队列
class BoundedBuffer {
final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition();
final Object[] items = new Object[100];
int putptr, takeptr, count;
public void put(Object x) throws InterruptedException {
lock.lock();
try {
while (count == items.length)
notFull.await();
items[putptr] = x;
if (++putptr == items.length) putptr = 0;
++count;
notEmpty.signal();
} finally {
lock.unlock();
}
}
public Object take() throws InterruptedException {
lock.lock();
try {
while (count == 0)
notEmpty.await();
Object x = items[takeptr];
if (++takeptr == items.length) takeptr = 0;
--count;
notFull.signal();
return x;
} finally {
lock.unlock();
}
}
}
使用了两个condition
同步工具
Semaphore
类似占坑
CyclicBarrier
阶段性使进度一致
CountDownLatch
一人通知多人/多人通知一人
Exchanger
线程间数据交换,都到达则自然交换
java开发中几种常见的线程池的更多相关文章
- Android 四种常见的线程池
引入线程池的好处 1)提升性能.创建和消耗对象费时费CPU资源 2)防止内存过度消耗.控制活动线程的数量,防止并发线程过多. 我们来看一下线程池的简单的构造 public ThreadPoolExec ...
- 2019.12.11 java程序中几种常见的异常以及出现此异常的原因
1.java.lang.NullpointerException(空指针异常) 原因:这个异常经常遇到,异常的原因是程序中有空指针,即程序中调用了未经初始化的对象或者是不存在的对象. 经常出现在创建对 ...
- iOS开发中几种常见的存储方式
1.archive 归档 数据的保存 1: let result = NSKeyedArchiver.archiveRootObject(contacts, toFile: path as Strin ...
- [ 转载 ] Java开发中的23种设计模式详解(转)
Java开发中的23种设计模式详解(转) 设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类 ...
- Java开发中常见的危险信号(中)
本文来源于我在InfoQ中文站原创的文章,原文地址是:http://www.infoq.com/cn/news/2013/12/common-red-flags-in-java-1 Dustin Ma ...
- Java开发中常见的危险信号(上)
本文来源于我在InfoQ中文站原创的文章,原文地址是:http://www.infoq.com/cn/news/2013/12/common-red-flags-in-java-1 Dustin Ma ...
- 编写高质量代码:改善Java程序的151个建议(第一章:JAVA开发中通用的方法和准则)
编写高质量代码:改善Java程序的151个建议(第一章:JAVA开发中通用的方法和准则) 目录 建议1: 不要在常量和变量中出现易混淆的字母 建议2: 莫让常量蜕变成变量 建议3: 三元操作符的类型务 ...
- Spring RestTemplate中几种常见的请求方式
https://github.com/lenve/SimpleSpringCloud/tree/master/RestTemplate在Spring Cloud中服务的发现与消费一文中,当我们从服务消 ...
- Java开发中所涉及的常用远程调用
根据<Spring in Action>一书中指出,Java开发中常见的远程过程调用(RPC),常见的有一下四种方式: 1.远程方法调用(RMI) 2.Caucho的Hessian和Bur ...
随机推荐
- [struts2学习笔记] 第五节 编写struts2的action代码
本文地址:http://blog.csdn.net/sushengmiyan/article/details/40479299 官方文档: http://struts.apache.org/relea ...
- Struts 2 之文件上传
如果要获得上传文件的原始名称,需要定义一个String类型的属性,属性名必须为***FileName,其中***为File属性的名称:同理,如果要获取该文件的MIME类型,需要定义一个***Conte ...
- RxJava在Android中使用场景详解
RxJava 系列文章 <一,RxJava create操作符的用法和源码分析> <二,RxJava map操作符用法详解> <三,RxJava flatMap操作符用法 ...
- linux及windows文件共享
http://blog.csdn.net/pipisorry/article/details/51812022 本文主要说明 linux和windows文件共享, windows和ubuntu互相访问 ...
- TCP的发送系列 — tcp_sendmsg()的实现(一)
主要内容:Socket发送函数在TCP层的实现 内核版本:3.15.2 我的博客:http://blog.csdn.net/zhangskd 上一篇blog讲的是send().sendto().sen ...
- linux shell 判断文件是否存在等符号
-a file exists. -b file exists and is a block special file. -c file exists and is a character spec ...
- Swift基础之显示波纹样式
最近项目用到了蓝牙连接,搜索设备的内容,其中需要搜索过程中出现波纹的动画效果,在这里将项目中OC语言编写的这种动画效果,转换成Swift编写,下面简单介绍说明一下代码. 这里用到了两种方法实现波纹效果 ...
- 择天记OL体验截图
- Java与C之间的socket通信
最近正在开发一个基于指纹的音乐检索应用,算法部分已经完成,所以尝试做一个Android App.Android与服务器通信通常采用HTTP通信方式和Socket通信方式.由于对web服务器编程了解较少 ...
- TCP/IP入门(1) --链路层
/** 本博客由汗青ZJF整理并发布, 转载请注明出处: http://blog.csdn.net/zjf280441589/article/category/1854365 */ TCP/IP体系结 ...