java并发和线程池简介
来源:互联网 发布:网络劫持什么意思 编辑:程序博客网 时间:2024/06/07 02:35
并发简介
什么时候需要并发
对于单核cpu运行的时候,如果前面的任务线程阻塞了,或者在响应某些事件时,为了保证其他事件任务也可以正常执行,cpu将任务时间进行切片,cpu一般有自己的调度,在不同时间调用不同任务,这个时候就需要并发。
看起来cpu像是能够同时执行多个任务,实际上是在不同任务上来回切换执行。(可能有些人要问切换难道不消耗时间吗),一般来说时间非常短暂,但是当前cpu只有一个任务执行的话,那么就不需要多此一举
实现并发最直接的方式是在操作系统级别使用进程。
并发线程,并不是创建的越多越好,一般有自己的负载极限与额外开支,可参考spring-webflux
ErLang 并发语言->适合游戏开发
java的线程机制是抢占式的,优先级高的被调度的几率更高,而不是代表他一定先执行
定义任务
在java中我们描述任务一般用于实现Runnable接口。并且编写run()方法(注意main方法也是一种线程)
第二种我们继承Thread类,然后将我们实现Runnable对象传入Thread的构造器,像这样:new Thread(new Runnable(的实现类)).start();
在使用Thread的时候,由于他要申请一个线程并且完成自己的注册,那么他将会只需获得一个引用,我们知道垃圾回收机制不会回收当前已有引用的对象,那么在run方法执行完成前他都不会被回收执行完了也不一定会被立即回收,要等待CPU对应的回收调度。
Executor类
JUC中提供了Executor执行器间接的帮助我们管理Thread对象
使用Executors的静态方法方法创建ExecutorService(继承自Executor,它是一种具有声明周期的Executor),可以调用他的execute方法:execute(Runnable runnable)
创建ExecutorService的几种常见方法:
/** * 学习之前先看看,Executors中的创建线程池所调用的公共方法 * @param corePoolSize 设置线程池中保存的线程数,不管是不是闲置状态 * @param maximumPoolSize 线程池中最大线程数 * @param keepAliveTime 当线程数过高时,闲置线程在终结前等待新任务的的最大时间 * @param unit 单位时间 * @param workQueue 在任务执行前的工作队列 */public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler); }
- Executors.newCachedThreadPool()–一般作为我们的首选方式
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); } //SynchronousQueue使用非公平工作队列
创建一个用于产生新Thread的线程池,可以被重用只要当前仍是有效的,可以明显的提高工程中执行很多短时同步任务,当线程池中有失效的线程时候,他就会创建一个新的线程来弥补之前的线程。</br>
+ Executors.newFixedThreadPool(int number)–当可以掌握自己需要多少的时候
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); } //LinkedBlockingQueue 感觉字面是链式阻塞队列,遵循FIFO
可以一次传入number的值,那么就会对应数量的线程,可以有效的限制线程的数量。
+ Executors.newScheduledThreadPool(int number)–可以延迟调度
创建一个线程池,可以在给定的时间后延迟运行,或者周期性地执行。(不是很熟悉感觉可以运用于batch之类的)
+ Executors.newWorkStealingPool()–减少队列中的竞争
public static ExecutorService newWorkStealingPool(int parallelism) { return new ForkJoinPool //这里调用的ForkJoinPool,这里不做详细解释 (parallelism, ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, true); }
创建持有足够的线程的线程池来支持给定的并行级别,该方法还会使用多个队列来减少竞争.
感兴趣的话click:https://stackoverflow.com/questions/41337451/detailed-difference-between-java8-forkjoinpool-and-executors-newworkstealingpool
下面是我自己的渣翻译:
传统的线程池会保有一个队列,并且会锁着这个队列,当有一个任务出列时就会解锁这个队列,如果有很多任务时间短的任务,那么就会在这个队列里面不断竞争,可以使用一个无锁来解决,但是无法从根底解决问题 。
现在的线程池使用工作窃取-每一个线程拥有自己的队列,当线程池执行一个任务的时候,他只会进入属于他自己的队列中,当线程池想要出列一个任务的时候,他先将自己队列中去寻找一个,如果队列中没有任务,那么他回去别的线程队列中偷取,这样可以降低线程池中的竞争从而提高效率。
newWorkStealingPool会去创建一个拥有许多线程的工作窃取可利用的线程池。
但是同时也暴露出了一个问题,如果我有4核cpu,那么总共就会创建4个线程池,如果其中一个任务阻塞了,比如:一个同步IO流,我没有办法完全利用我的CPUS,因为我所想要的是在任何时刻都是活跃的4个线程,比如,4个正在AES加密中,另外140个正在等待IO完成。
这个是由ForkJoinPool所提供的,如果你的任务又产生了许多子任务并且需要等待子任务完成的话,线程池为了防CPU饱和会重新注入一些新的有效线程。值得一提的是,ForkJoinPool就是使用这种工作窃取。
在说了这么多之后,现在的应用已经是在向创建大量可用线程池,异步流,无锁容器来防止阻塞的趋势靠近了,这个通常也给与我们很好的反馈信息了
- newSingleThreadExecutor可以理解为线程数量为1的FixedThreadPool
/**从代码中可以看到与Fixed的类似,表面区别在于它的第一个参数是1,但其实他额外有一种并发保 证,如果由多个任务执行,那么下一个任务必须等到上一个任务执行完,所有任务使用相同线程*/ public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }
- java并发和线程池简介
- Java并发之线程池简介
- Java 并发:Executors 和线程池
- Java 并发Executors 和线程池
- Java 并发:Executors 和线程池
- Java 并发:Executors 和线程池
- Java 并发:Executors 和线程池
- Java 并发:Executors 和线程池
- Java 并发:Executors 和线程池
- Java并发:终止线程和关闭线程池
- 《并发编程》--14.Java线程池和自定义线程
- java并发编程(十五)----(线程池)java线程池简介
- java中的并发和线程
- Java线程通信和线程并发库
- JAVA并发-线程状态和线程组
- 【Java 并发系列】Java线程池的分析和使用
- 并发(1)--线程池简介
- java多线程与并发之java线程简介(一)
- Scrapy-redis分布式爬虫
- 属性.properties中文转换
- Openlayers对接PIGS 山海易绘
- OpenLayers跨域问题的tomcat下的设…
- 解决websphere过期的问题
- java并发和线程池简介
- 安装版的tomcat6.0 内存设置…
- 从人的本能出发谈游戏设计
- iFrame跨域解决办法
- 调试js框架
- Ripple安全操作系列一:使用…
- 2013年总结
- VML绘制圆角矩形的方法
- excle文件转为shp文件说明