Java并发编程---线程 - Go语言中文社区

Java并发编程---线程


线程的创建方式
1、继承Thread类。
2、实现Runnable接口。
3、匿名内部类的方式。
4、带返回值的线程。
5、定时器。Timer
6、线程池的实现。
7、Lambda表达式的实现。
run和start的区别?
run()方法内部是相关任务逻辑入口,由线程运行时直接调用。
start()方法是启动相应的线程,但是线程何时能够运行是由线程调度器决定的。

wait和sleep的区别?
wait()会释放当前线程锁,并将线程放入任务调度队列,直到被notify时线程才会被唤醒。
sleep()是线程睡眠一段时间,时间一到继续执行,不会释放锁

interrupt和stop的区别?
线程执行stop操作,那么线程会直接终止。
线程执行interrupt操作,线程并未中断或是结束运行。interrupt()是对当前线程做了一个“中断”的标记,开发者通过判断这个标记来自行结束线程的运行。

有些方法会修改线程的标记状态,比如sleep(),wait(),Thread.interrupt()方法。

在sleep()之前调用interrupt()时,当代码执行到sleep()时,会立马抛出异常,并将中断标识位重置为false。
在sleep()之后调用interrupt(),当执行了interrupt()后会打断线程的休眠状态。
线程池
ThreadPoolExecutor创建线程池
从源码中可以看出,ThreadPoolExecutor的构造方法有四个,但是最后都会调用到参数最多的那一个去,只不过对是否有ThreadFactory和handler进行了类的区分。
在这里插入图片描述
构造方法里的各个参数表示什么意思呢?
core
corePoolSize:核心线程数,这些数目的线程会一直存活,即使它们处在空闲状态。只有在工作队列满了的情况下,才会创建超出这个数量的线程。需要注意的是在刚刚创建ThreadPoolExecutor的时候,线程池还是0个线程,并没有初始化所有的核心线程数。随着任务的提交,核心线程慢慢初始化,直到指定的corePoolSize个线程。
maximumPoolSize:线程池中允许的最大线程数。当队列中任务已满,并且当前线程数小于最大线程数,那么就会创建新的线程。
keepAliveTime:线程空闲时间,当线程空闲时间达到这个值得时候,线程会退出,直到线程数量 = corePoolSize。
workQueue:阻塞队列,存储的是等待执行的任务。
threadFactory:线程工厂。用来创建线程的。如果没有设置则使用默认的线程工厂,创建出来的线程拥有相同的优先级,并且设置了守护性,同时也设置了线程名称的格式。
handler:拒绝策略。当workQueue满了,并且没有空闲的线程,就会由这个策略来处理。
默认的是: 直接抛出异常。
使用调用者所在线程执行任务。
丢弃队列中最靠前的任务,并执行当前任务。
直接丢弃当前任务。
AbortPolicy:丢弃任务并抛出RejectExecutionException异常。
DiscardPolicy:丢弃任务,但是不抛出异常。
DiscardOldestPolicy:丢弃队列最前面的任务,然后重新提交被拒绝的任务。
CallerRunsPolicy:由调用线程处理该任务。

常用的workQueue的实现
SynchronousQueue:同步队列,这是没有任何内部容量的。
ArrayBlockingQueue:数组支持的有界阻塞队列。按FIFO原则对元素进行排序。队列满了再放任务就会导致操作受阻。空队列获取元素也会导致操作受阻。

LinkedBlockingQueue:无限队列,基于的是链表。说是无限,其实是Integer的max_value。

Executors创建线程池
用Exectuor创建线程池的常用方法是:
看Executors的源码在这里插入图片描述
里面的方法其实也是调用ThreadPoolExecutor而已,只不过各项参数默认设置了。
但是在alibaba的java开发规范中明确指出不允许使用Executors创建线程池。
Executor创建线程池的弊端
那么为什么不推荐用Executors去创建线程池呢?
newFixedThreadPool和singleThreadPool允许的请求队列长度为Integer.max_value,可能会堆积大量的请求,导致OOM。
newCacheThreadPool和ScheduledThreadPool允许创建的线程池数量是Integer.max_value会创建大量的线程,从而导致OOM.

综上所述,正确的创建线程池的方法就是用ThreadPoolExecutor去创建,设置所需要的参数。在遇到错误的时候抛出异常,然后对异常进行处理。
针对线程池的异常应该怎么处理呢

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_33628614/article/details/103507858
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-02-25 01:17:28
  • 阅读 ( 844 )
  • 分类:Linux

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢