重拾系列之——Java多线程

线程

进程的最小执行单元,CPU资源分配的基本单位。

线程的六种状态
1、NEW

新创建,但是没有调用start()方法,线程还没有启动

2、RUNNABLE

调用了start()后,进入可运行状态,jvm正在执行线程的run方法

3、BLOCKED:

线程状态被阻塞。发生阻塞式I/O时,进入synchronize方法或代码块执行失败时,其他线程 持有锁时会进入该状态。

4、WAITING:

执行完某个特定的方法后,会等待其他线程执行完毕,此时线程进入等待状态。调用Object#wait()时进入等待状态,调用Thread.join时,调用LockSupport.park时,遇到Object.notify()、Object.notifyAll()、LockSupport.unpark()时又变成可运行状态,或者叫唤醒会进入该状态。

5、TIMED_WAITING:

等待一段时间,时间到了就会转成可运行状态。调用Thread.sleep、Thread.join、Object.wait等方法时触发

6、TERMINATED

线程任务执行完,或者抛异常时,就会进入终止状态

volatile 关键字

  • 轻量级的同步锁,可修饰成员变量,用来确保变量的更新操作通知到其他线程中
  • 非volatile修饰,读写变量时,每个线程将变量从线程内存拷贝到CPU缓存中
  • 读写volatile修饰的变量时,JVM会保证这个变量直接从内存中读取,调过了CPU缓存
  • 保证了线程间可见,进制指令重排

线程池

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler) {
		//...
}

参数

corePoolSize

核心线程数,即使空闲也不会销毁

maximumPoolSize

线程池最大线程数。一个任务提交后,首先查有没有空闲存活的线程,有则直接执行;没有则会缓存到工作队列中,如果工作队列满了,才会创建一个新线程,然后从工作队列的头部取出一个任务交给新线程处理,将刚提交的任务放到工作队列的尾部

keepAliveTime

空闲线程的存活时间。如果一个线程处于空闲状态,并且当前线程数大于corePoolSize,那么指定时间后,这个空闲线程会被销毁。

unit:时间单位
workQueue:

工作队列。一个任务提交,没有空闲线程时,会将任务加入队列中,任务调度时再取出

  • ArrayBlockingQueue:基于数组的有界队列。线程数达到corePoolSize后,新任务来,翻到队列尾部,如果队列满了,则新建一个线程,直到达到maximumPoolSize,超过maximumPoolSize则拒绝
  • LinkedBlockingQuene:基于链表的无界队列,corePoolSize满了之后,不会新建线程,而是一直存入队列,因为队列最大容量为Interger.MAX,maximumPoolSize不起作用
  • SynchronousQuene:不缓存任务的队列 PriorityBlockingQueue:具有优先级的无界队列
threadFactory:线程工厂。可设置线程名称,是否为守护线程
handler:拒绝策略
  • CallerRunsPolicy:会执行被拒任务的run方法,除非线程池被shutdown
  • AbortPolicy:直接丢弃任务,并抛异常 DiscardPolicy:直接丢弃任务,什么都不做
  • DiscardOldestPolicy:丢弃入队最早的任务,然后尝试将丢弃的任务存入队列

常见线程池

  • newFixedThreadPool:定长线程池,使用无界队列,线程池无任务时会立刻销毁
  • newSingleThreadExecutor:单线程的线程池,同样使用无界队列
  • newCachedThreadPool:可缓存的线程池,没有核心线程数,当线程没有任务60秒后就回收空闲线程,使用有界队列
  • newScheduledThreadPool:支持线程定时操作和周期性操作
不建议使用 Executors静态工厂构建线程池

主要原因如下:

1、FixedThreadPool 和 SingleThreadPool使用的是无界队列,容量太大,可能堆积大量请求容易导致OOM
2、CachedThreadPool 和 ScheduledThreadPool:允许的创建线程数量为太大,可能会创建大量的线程,从而导致OOM

最后

附上思维导图一张
在这里插入图片描述

欢迎关注我的个人微信公众号,【优了个秀】和你每天进步一点点
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值