一 线程状态及生命周期
1. 初始(NEW):新创建了一个线程对象,但还没有调用start()方法。
2. 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。
线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running)。
3. 阻塞(BLOCKED):表示线程阻塞于锁。
4. 等待(WAITING):进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。
5. 超时等待(TIMED_WAITING):该状态不同于WAITING,它可以在指定的时间后自行返回。
6. 终止(TERMINATED):表示该线程已经执行完毕。
https://blog.csdn.net/pange1991/article/details/53860651
二 线程池作用
当存在大量并发任务时,创建、销毁线程需要很大的开销,运用线程池可以大大减小开销。
三 ThreadPoolExecutor 线程池类
重要参数:
1、corePoolSize核心线程数大小,当线程数<corePoolSize ,会创建线程执行runnable
2、maximumPoolSize 最大线程数, 当线程数 >= corePoolSize的时候,会把runnable放入workQueue中
3、keepAliveTime 保持存活时间,当线程数大于corePoolSize的空闲线程能保持的最大时间。
4、unit 时间单位
5、workQueue 保存任务的阻塞队列
6、threadFactory 创建线程的工厂
7、handler 拒绝策略
任务执行顺序:
1、当线程数小于corePoolSize时,创建线程执行任务。
2、当线程数大于等于corePoolSize并且workQueue没有满时,放入workQueue中
3、线程数大于等于corePoolSize并且当workQueue满时,新任务新建线程运行,线程总数要小于maximumPoolSize
4、当线程总数等于maximumPoolSize并且workQueue满了的时候执行handler的rejectedExecution。也就是拒绝策略。
可参考 https://www.cnblogs.com/shijiaqi1066/p/3412300.html
三 Executor 框架类结构
- Executor是一个接口,他是Executor框架的基础,它将任务的提交与任务的执行分离。
- ThreadPoolExecutor是线程池的核心实现类,用来执行被提交的任务。
- ScheduledThreadPoolExecutor是一个实现类,可以在给定的延迟后运行命令,或者定期执行命令。ScheduledThreadPoolExecutor 比 Timer 更灵活,功能更强大。
- Future接口和它的实现FutureTask类,代表异步计算的结果。
- Runnable和Callable接口的实现类,都可以被ThreadPoolExecutor 或 ScheduledThreadPoolExecutor 执行
从上往下看
Executor,是一个可以提交可执行(Runnable)任务的Object,这个接口解耦了任务提交和执行细节(线程使用、调度等),Executor主要用来替代显示的创建和运行线程;
ExecutorService提供了异步的管理一个或多个线程终止、执行过程(Future)的方法;
AbstractExecutorService提供了ExecutorService的一个默认实现,这个类通过RunnableFuture(实现类FutureTask)实现了submit, invokeAny, invokeAll几个方法;
ThreadPoolExecutor是ExecutorService的一个可配置的线程池实现,它的两个重要的配置参数:corePoolSize(线程池的基本大小,即在没有任务需要执行的时候线程池的大小,并且只有在工作队列满了的情况下才会创建超出这个数量的线程。这里需要注意的是:在刚刚创建ThreadPoolExecutor的时候,线程并不会立即启动,而是要等到有任务提交时才会启动,除非调用了prestartCoreThread/prestartAllCoreThreads事先启动核心线程。再考虑到keepAliveTime和allowCoreThreadTimeOut超时参数的影响,所以没有任务需要执行的时候,线程池的大小不一定是corePoolSize。), maximumPoolSize(线程池中允许的最大线程数,线程池中的当前线程数目不会超过该值。如果队列中任务已满,并且当前线程个数小于maximumPoolSize,那么会创建新的线程来执行任务。这里值得一提的是largestPoolSize,该变量记录了线程池在整个生命周期中曾经出现的最大线程个数。为什么说是曾经呢?因为线程池创建之后,可以调用setMaximumPoolSize() 改变运行的最大线程的数目。);
ScheduledExecutorService 是添加了调度特性(延迟或者定时执行)的ExecutorService;
ScheduledThreadPoolExecutor是具有调度特性的ExecutorService的池化实现;
Executors是一个Executor, ExecutorService, ScheduledExecutorService, ThreadFactory, Callable的工具类,它能满足大部分的日常应用场景。使用它创建线程池。
四 awk命令工作原理
awk 'BEGIN{ commands } pattern{ commands } END{ commands }'
- 第一步:执行
BEGIN{ commands }
语句块中的语句; - 第二步:从文件或标准输入(stdin)读取一行,然后执行
pattern{ commands }
语句块,它逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕。 - 第三步:当读至输入流末尾时,执行
END{ commands }
语句块。
BEGIN语句块在awk开始从输入流中读取行之前被执行,这是一个可选的语句块,比如变量初始化、打印输出表格的表头等语句通常可以写在BEGIN语句块中。
END语句块在awk从输入流中读取完所有的行之后即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,它也是一个可选语句块。
pattern语句块中的通用命令是最重要的部分,它也是可选的。如果没有提供pattern语句块,则默认执行{ print }
,即打印每一个读取到的行,awk读取的每一行都会执;行该语句块。
awk 命令举例 :awk 'BEGIN{ sum=0; print "总和:" } { print $1"+"; sum+=$1 } END{ print "等于"; print sum }'
常见内置变量:
$n 当前记录的第n个字段,比如n为1表示第一个字段,n为2表示第二个字段。
$0 这个变量包含执行过程中当前行的文本内容。
五 JAVA集合框架
i 是接口 ,c是类