关于一些基础的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. 虚 ...
随机推荐
- react-native-image-picker 运用launchCamera直接调取摄像头的缺陷及修复
在前几天用react-native进行android版本开发当中,用到了"react-native-image-picker"的插件:根据业务的需求:点击按钮-->直接调取摄 ...
- SpringBoot应用的前台目录
一.两个重要目录 templates:存放web页面的模板文件,需要在controller返回视图名称,框架转发才能找到的html. static :存放静态资源,如:html(放在这里可直接访问,如 ...
- Android学习——NDK交叉编译
原创作品,转载请注明出处,严禁非法转载.如有错误,请留言! email:40879506@qq.com 一. 环境1.GNU/Linux Ubuntu12.04操作系统(x86) 二. 下载NDK安装 ...
- 并发容器和框架之ConcurrentHashMap
了解HashMap的人都知道HashMap是线程不安全的(多线程下的put方法达到一定大小,引发rehash,导致闭链,最终占满CPU),同时线程安全的HashTable效率又令人望而却步(每个方法都 ...
- scrapy爬取豆瓣电影top250
# -*- coding: utf-8 -*- # scrapy爬取豆瓣电影top250 import scrapy from douban.items import DoubanItem class ...
- Python模块之 - logging
日志是非常重要的,最近有接触到这个,所以系统的看一下Python这个模块的用法.本文即为Logging模块的用法简介,主要参考文章为Python官方文档,链接见参考列表. Logging模块构成 组成 ...
- 众说纷纭的ul、ol、li
(1)提到ul ol li,大家都知道,就是三个列表标签,ul表示无需列表(unordered list),ol表示有序列表(oredr list), li 表示列表项(list item),之前我也 ...
- ios开发- 利用运行时(runtime)字典转模型
现在的ios开发中,我们通常会使用MVC模式.当我们拿到数据的时候,我们要把数据转成模型使用. 一般情况我们拿到的数据都是字典.这是我们就需要将字典转成模型对象了. 当对象的属性很少的时候,我们可以直 ...
- Hibernate--对象关系
在hibernate中,关联关系映射分为单向关联和双向关联.共有七种关系 ·@Many To One ·@One To Many(单向) ·@One To Many(多向) ·@One To One( ...
- NKOJ4191 Trie树
问题描述 字母(Trie)树是一个表示一个字符串集合中所有字符串的前缀的数据结构,其有如下特征: 1.树的每一条边表示字母表中的一个字母 2.树根表示一个空的前缀 3.树上所有其他的节点都表示一个 ...