Java并发篇

文章详细介绍了Java线程的六种状态,包括新建、可运行、终结、阻塞、等待和有时限等待,并对比了操作系统层面的五种状态。线程池的核心参数包括核心线程、救急线程、工作队列和拒绝策略。讨论了Sleep和Wait的区别,以及Lock和synchronized的特性,如互斥、同步、锁重入和公平锁/非公平锁的概念。最后提到了volatile关键字在多线程环境中的作用。
摘要由CSDN通过智能技术生成

一、线程有哪些状态

1. Java层面线程分为六种状态

新建、可运行、终结、阻塞、等待、有时限等待

 新建:当新建一个线程时,它没有和操作系统底层正在的线程关联起来,所以此时不会被cpu分配内存执行代码,只有调用线程的start方法变成RUNNABLE后才会与操作线程关联起来,交给CPU运行处理。只有RUNNABLE状态才会被分配CPU,其它状态不会被交给CPU执行相应的代码。

阻塞:当线程运行时会出现多个线程去争抢同一把锁,只有一个线程能成功,失败的线程就会变成BLOCKED阻塞状态。

等待:当一个线程成功抢到锁后,可能有一些条件不符合,还要去执行相应的条件,这个时候可以调用wait()方法,释放锁,进入WAITING等待状态。当将来条件满足了,由另一个线程调用notify()方法可以将等待的线程唤醒。唤醒后还要去重新争取锁,争取成功后就会变成可运行状态。

有时限的等待:等待时设置了一个时间,这种线程除了可以被notify()唤醒,还可以等时间到了被唤醒。还有一种就是线程调用了sleep(long)方法,sleep不会释放锁,就会变成等待状态,时间到了就会被唤醒。

 2.操作系统层面有五种状态:

新建、就绪、运行、终结、阻塞

 阻塞I/O:线程中有一些操作是由磁盘和网卡单独运行,不需要分配CPU,所以被归为阻塞I/O

二、线程池的核心参数 

 核心线程:线程池维护的最小线程数量,核心线程创建后不会被回收(注意:设置allowCoreThreadTimeout=true后,空闲的核心线程超过存活时间也会被回收)。

救急线程:会被回收的线程

workQueue:工作队列

存放待执行任务的队列:当提交的任务数超过核心线程数大小后,再提交的任务就存放在工作队列,任务调度时再从队列中取出任务。它仅仅用来存放被execute()方法提交的Runnable任务。工作队列实现了BlockingQueue接口。

handler:拒绝策略
当线程池线程数已满,并且工作队列达到限制,新提交的任务使用拒绝策略处理。可以自定义拒绝策略,拒绝策略需要实现RejectedExecutionHandler接口。

JDK默认的拒绝策略有四种:

AbortPolicy:丢弃任务并抛出RejectedExecutionException异常,默认拒绝策略。
DiscardPolicy:丢弃任务,但是不抛出异常。可能导致无法发现系统的异常状态。
DiscardOldestPolicy:丢弃队列最前面的任务,然后重新提交被拒绝的任务。
CallerRunsPolicy:由调用线程处理该任务

三、Sleep和Wait

 

四、lock和synchronized 

 

 

 互斥:所有的线程都去抢同一把锁,但最终只有一个线程能成功

同步:当一个线程抢到锁后,运行代码时,发现要调用另一个线程,那么此时这个线程就会进入等待状态,等另一个线程拿到锁唤醒。

锁重入:一个对象被锁多次,被锁几次就要解锁几次

获取等待状态,Lock有方法可以看到有哪些线程被阻塞了

公平锁和非公平锁:所有线程争抢同一把锁的时候,会有失败的线程,当这些失败的线程再次争抢同一把锁的时候,如果支持先来后到的原则就是公平锁,如果允许插队就是非公平锁。synchronized只支持非公平锁,Lock既支持非公平锁又支持公平锁。如果一个线程一直抢不到锁,Lock支持可打断,可超时,意思就是不抢这个锁了,或者超时了就不强了。但synchronized不支持可打断可超时。

多条件变量:多个等待队列

五、volatile

 volatile能否保证线程安全

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值