关于一些基础的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. 虚 ...
随机推荐
- 前端基础之CSS-Day13
1.CSS 语法 1.1.CSS 规则由两个主要的部分构成:选择器,以及一条或多条声明. selector { property: value; property: value; ... proper ...
- 用javascript做别踩白块游戏1
初学Javascript做的一个别踩白块小游戏,代码简陋,如下: <!DOCTYPE html> <html> <head> <!-- 禁用缩放功能 --&g ...
- 粒子系统(二):Canvas绘制精美图案
准备 IDE:Visual Studio Code Language:JavaScript / ECMAScript 6+ GitHub:Natural2D.JS 本文主要讲述 Particles - ...
- DOM节点删除之empty和remove区别
要移除页面上节点是开发者常见的操作,jQuery提供了几种不同的方法用来处理这个问题,这里我们开仔细了解下empty和remove方法 empty 顾名思义,清空方法,但是与删除又有点不一样,因为它只 ...
- Java线程池是如何诞生的?
时间回到2003年,那时我还是一个名不见经传的程序员,但是上级却非常看好我,他们把整个并发模块,都交给了我一个人开发. 这个星期,我必须要完成并发模块中非常重要的一个功能--线程池. 注:文末有福利 ...
- ACE工具概述
一:ACE简介 ADAPTIVE 通信环境(ACE,ADAPTIVE Communication Enviroment)是一种广泛的主机基础设施中间件,ACE可以免费获得,可以在http://ace. ...
- vue 插值,v-once,v-text, v-html
引入Vue.js ,通过script形式,vue官网语法记录 创建vue应用,数据和 DOM 已经被建立了关联,所有东西都是响应式的 1:插值 缺点:让你的网速慢,或者数据加载失败时,会在浏览器中直接 ...
- python3 Serial 串口助手的接收读取数据
其实网上已经有许多python语言书写的串口,但大部分都是python2写的,没有找到一个合适的python编写的串口助手,只能自己来写一个串口助手,由于我只需要串口能够接收读取数据就可以了,故而这个 ...
- JavaScript的作用;JS常见的三种对话框;==和===的区别;函数内部参数数组arguments在函数内部打印实参;JS的误区:没有块级作用域
JS:客户端(浏览器)脚本语言 弱类型 基于原型 事件驱动 不需要编译(直接运行) JS的作用:表单验证,减轻服务端的压力 添加页面动画效果 动态更改页面内容 Ajax网络请求 (一)常见的对 ...
- orabbix插件监控oracle表空间问题
我们安装好orabbix插件后,查看Tablespaces监控项是发项值为none,第一反应是没监控成功,其实不然. 1.我们打开orabbix监控项参数的路径,下面为Tablespaces的sql代 ...