关于一些基础的Java问题的解答(六)
26. ThreadPool用法与优势
- 降低资源消耗:通过重复利用已创建的线程降低线程创建和销毁造成的消耗
- 提高响应速度:当任务到达时,任务可以不需要等到线程创建就能立即执行
- 提高线程的可管理性:线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控
- ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
- corePoolSize(基本线程池大小):当提交一个任务到线程池时,线程池会创建一个线程来执行任务,即使其他空闲的基本线程能够执行新任务也会创建线程,等到需要执行的任务数大于基本线程池大小时就不再创建。线程池有一个prestartAllCoreThreads方法用来提前创建并启动所有基本线程
- maximumPoolSize(最大线程池大小):线程池允许创建的最大线程数,必须大于基本线程池大小。线程池中含有一个任务阻塞队列,如果队列满了,并且已创建的线程数小于最大线程数,则线程池会再创建新的线程执行任务
- keepAliveTime(线程活动保持时间):线程池的工作线程空闲后,保持存活的时间。所以如果任务很多,并且每个任务执行的时间比较短,可以调大这个时间,提高线程的利用率
- unit(线程活动保持时间的单位):前一个参数的时间单位
- workQueue(工作队列):用于保存等待执行的任务的阻塞队列,如果当任务提交时基本线程池中已没有空闲线程,则任务会被放入工作队列等待
- threadFactory(线程工厂,可选参数):创建一个新线程时会调用其newThread方法,可以初始化一些信息
- handler(饱和处理器):当队列和线程池都满了,说明线程池处于饱和状态,那么就会使用处理器处理提交的新任务。ThreadPoolExecutor内部提供了一些handler的静态实现类:
- AbortPolicy:直接抛出异常RejectedExecutionException
- CallerRunsPolicy:使用调用者所在线程来运行任务
- DiscardOldestPolicy:丢弃队列头的任务,并执行当前任务
- DiscardPolicy:什么也不做,放弃掉该任务
- // 为每个任务创建一个新线程或回收利用旧线程的线程池
- ExecutorService service1 = Executors.newCachedThreadPool();
- // 创建指定数目线程的线程池
- ExecutorService service2 = Executors.newFixedThreadPool(nThreads);
- // 线程数量固定为1的线程池,拥有无界的工作队列
- ExecutorService service3 = Executors.newSingleThreadExecutor();
以上三种线程池为比较常用的线程池,其余的不再探讨。
- // 传入一个Runnable接口处理任务
- executor.execute(runnable);
- // 传入一个Callable接口处理任务,返回Future对象代表任务返回值
- Future<Object> result = executor.submit(callable);
- // 使用get方法获取具体内容
- result.get();
- // 关闭线程池,中断空闲线程
- executor.shutdown();
- // 关闭线程池,中断所有线程
- executor.shutdownNow();
综上,线程池的工作流程为:
27. Concurrent包里的工具:ArrayBlockingQueue、CountDownLatch等等
- CopyOnWriteArrayList:写时拷贝列表,对容器的写入操作将导致创建整个底层数组的副本,而原数组保存在原地,使得当数组在被修改时,读取可以安全的执行。修改完成时,一个原子性的操作会把新数组换入,使得新的读取操作可以看到修改
- CopyOnWriteArraySet:与CopyOnWriteArrayList类似的集合
- ConcurrentHashMap:详见问题11
- ConcurrentLinkedQueue:一个线程安全的队列
- DelayQueue:延迟队列,是一个无界阻塞队列,对于放入的元素实现延迟接口,设定延迟时间,元素只有过了延迟时间后才能被取走
- LinkedBlockingQueue:阻塞队列,LinkedBlockingQueue 可以指定容量,也可以不指定,不指定的话,默认最大是Integer.MAX_VALUE,其中主要用到put和take方法,put方法在队列满的时候会阻塞直到有队列成员被消费,take方法在队列空的时候会阻塞,直到有队列成员被放进来
- PriorityBlockingQueue:优先级阻塞队列,与优先级队列相似,具有阻塞的特点
- Atomic类,原子类,各种包装类型的同步类,可以使用compareAndSet形式的方法来更新变量
- CountDownLatch:一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。其构造方法可以指定计数次数,当其countDown方法被调用时次数减一,而调用await方法(可以设置超时)会使当前线程一直被阻塞,直到计时器的值为0
- CyclicBarrier:回环栅栏,通过它可以实现让一组线程等待至某个状态之后再全部同时执行。叫做回环是因为当所有等待线程都被释放以后,CyclicBarrier可以被重用。其构造方法可以指定线程数,还可以传入Runnable表示所有线程到达状态后要执行的内容。线程调用其await方法时表示线程已到达指定状态并被阻塞,当有所有线程都到达状态时,线程才可以继续往下执行。调用其reset方法可以重复使用。
- Exchanger:用于两个线程交换数据的辅助类,调用exchange方法后线程会被阻塞知道另一个线程调用exchange方法(可以设置超时)
- ReadWriteLock:读写锁允许我们拥有多个读者,对向数据结构相对不频繁的写入但频繁读取做了优化。我们分别可以调用readLock和writeLock方法获取读锁和写锁,使用lock和unlock方法来加锁和解锁。
- Semaphore:信号量,可以控同时访问的线程个数(通过构造函数设置),通过 acquire方法 获取一个许可,如果没有就等待,而 release方法 释放一个许可。
28. wait()和sleep()的区别
29. foreach与正常for循环效率对比
30. Java IO与NIO
面向流与面向缓冲
阻塞IO与非阻塞IO
选择器(Selector)
关于一些基础的Java问题的解答(六)的更多相关文章
- 关于一些基础的Java问题的解答(一)
学习一门语言基础是非常重要的,因此本文总结了一些常见的Java基础问题的解答,希望可以帮到大家. 1. 九种基本数据类型的大小,以及他们的封装类. 9种基本数据类型 基本类型 包装类型 大小 bool ...
- 关于一些基础的Java问题的解答(七)
31. 反射的作用与原理 简单的来说,反射机制其实就是指程序在运行的时候能够获取自身的信息.如果知道一个类的名称或者它的一个实例对象, 就能把这个类的所有方法和变量的信息(方法名,变量名,方法,修饰符 ...
- 关于一些基础的Java问题的解答(四)
16. Java面向对象的三个特征与含义 java中的面向对象的三大基本特征分别是:封装.继承.多态: 封装:把过程和数据包围起来,对数据的访问只能通过已定义的界面,主要是方便类的修改 继承:对象的一 ...
- 关于一些基础的Java问题的解答(五)
21. 实现多线程的两种方法:Thread与Runable 在Java中实现多线程编程有以下几个方法: 1.继承Thread类,重写run方法 public class Test { public s ...
- 关于一些基础的Java问题的解答(三)
11. HashMap和ConcurrentHashMap的区别 从JDK1.2起,就有了HashMap,正如上一个问题所提到的,HashMap与HashTable不同,不是线程安全的,因此多线程 ...
- 关于一些基础的Java问题的解答(二)
6. Hashcode的作用 官方对于hashCode的解释如下: Whenever it is invoked on the same object more than once during an ...
- 黑马程序员:Java基础总结----java注解
黑马程序员:Java基础总结 java注解 ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! java注解 lang包中的基本注解 @SuppressWarnings ...
- java面试题—精选30道Java笔试题解答(二)
摘要: java面试题-精选30道Java笔试题解答(二) 19. 下面程序能正常运行吗() public class NULL { public static void haha(){ System ...
- Java基础:Java的四种引用
在Java基础:java虚拟机(JVM)中,我们提到了Java的四种引用.包括:强引用,软引用,弱引用,虚引用.这篇博客将详细的讲解一下这四种引用. 1. 强引用 2. 软引用 3. 弱引用 4. 虚 ...
随机推荐
- 如何将portfolio产品图片上的悬停去掉?
在Avada主题里,文章和portfolio的分类界面的图片,鼠标移入后都会出现这个东西 那么如何把它去掉,改为直接点击产品图片后进入产品详情页呢? 在theme option里搜索image rol ...
- emqtt 试用(八)ssl认证 - 代码验证
参考链接:http://emqtt.com/clients#java http://docs.emqtt.cn/zh_CN/latest/config.html#mqtt-ssl-8883 一.单向认 ...
- maven入门(1-4)使用eclipse构建maven项目
1. 安装m2eclipse插件 要用Eclipse构建Maven项目,我们需要先安装meeclipse插件 点击eclipse菜单栏Help->Eclipse Marketplac ...
- Python进程
(先分享一个Python在线编程的网站http://www.pythontip.com/coding/skulpt-interactive/) (本文为原创作品,欢迎转载,转载请注明出处) 一.概念 ...
- oracle11g导出表时会发现少表,空表导不出解决方案
oracle11g导出表时会发现少表,空表导不出解决方案. 一:背景引入 oracle11g用exp命令导出数据库表时,有时会发现只导出了一部分表时而且不会报错,原因是有空表没有进行导出,之前一直 ...
- python/ORM操作详解
一.python/ORM操作详解 ===================增==================== models.UserInfo.objects.create(title='alex ...
- Android:CheckBox控件
1)ChexkBox继承自CompoundButton组件: 2)isChecked()--确定是否选中:setChecked(bool checked)--设置选中或取消选中: 3)监听事件:Com ...
- 存图方式---邻接表&邻接矩阵&前向星
基于vector存图 struct Edge { int u, v, w; Edge(){} Edge(int u, int v, int w):u(u), v(v), w(w){} }; vecto ...
- docker 安装与学习
本文在CentsOS下安装Docker 1.安装前准备工作 系统要求: 在CentOS下需要64位的CentsOS 7 OS requirements To install Docker, you ...
- [ABP]浅谈工作单元 在整个 ABP 框架当中的应用
ABP在其内部实现了工作单元模式,统一地进行事务与连接管理. 其核心就是通过 Castle 的 Dynamic Proxy 进行动态代理,在组件注册的时候进行拦截器注入,拦截到实现了 Unit Of ...