1.请简述一下线程的sleep()方法和yield()方法有什么区别?
回答:
①sleep()方法给其他线程运行机会时不考虑线程的优先级,因此会给低优先级的线程以运行的机会;yield()方法只会给相同优先级或更高优先级的线程以运行的机会;
② 线程执行sleep()方法后转入阻塞(blocked)状态,而执行yield()方法后转入就绪(ready)状态;
③ sleep()方法声明抛出InterruptedException,而yield()方法没有声明任何异常;
④ sleep()方法比yield()方法(跟操作系统CPU调度相关)具有更好的可移植性。
2.请说出你所知道的线程同步的方法
答:wait():使一个线程处于等待状态,并且释放所持有的对象的lock。
sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException异常。
notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。
Allnotity():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。
3.请说明一下sleep() 和 wait() 有什么区别?
答:sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,把执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。
wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。
4.请详细描述一下线程从创建到死亡的几种状态都有哪些?
答:1. 新建( new ):新创建了一个线程对象。
2. 可运行( runnable ):线程对象创建后,其他线程(比如 main 线程)调用了该对象 的 start ()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获 取 cpu 的使用权 。
3. 运行( running ):可运行状态( runnable )的线程获得了 cpu 时间片( timeslice ) ,执行程序代码。
4. 阻塞( block ):阻塞状态是指线程因为某种原因放弃了 cpu 使用权,也即让出了 cpu timeslice ,暂时停止运行。直到线程进入可运行( runnable )状态,才有 机会再次获得 cpu timeslice 转到运行( running ) 状态。阻塞的情况分三种:
(一). 等待阻塞:运行( running )的线程执行 o . wait ()方法, JVM 会把该线程放 入等待队列( waitting queue )中。
(二). 同步阻塞:运行( running )的线程在获取对象的同步锁时,若该同步锁 被别的线程占用,则 JVM 会把该线程放入锁池( lock pool )中。
(三). 其他阻塞: 运行( running )的线程执行 Thread . sleep ( long ms )或 t . join ()方法,或者发出了 I / O 请求时, JVM 会把该线程置为阻塞状态。 当 sleep ()状态超时、 join ()等待线程终止或者超时、或者 I / O 处理完毕时,线程重新转入可运行( runnable )状态。
5. 死亡( dead ):线程 run ()、 main () 方法执行结束,或者因异常退出了 run ()方法,则该线程结束生命周期。死亡的线程不可再次复生。
5.线程的种类
答:Java通过Executors提供四种线程池:newCashedTheadPool (可缓存的线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程)
newFixedThreadPool(创建一个定长的线程池,可控制线程最大并发数,超出的线程会在队列中等待)
newScheduledThreadPool(定长线程池,支持定时及周期性任务执行)
newSingleThreadPool(单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序FIFO LIFO 优先级)执行
6.请简要说明一下JAVA中cyclicbarrier和countdownlatch的区别分别是什么?
答:CountDownLatch和CyclicBarrier都能够实现线程之间的等待,只不过它们侧重点不同:
CountDownLatch一般用于某个线程A等待若干个其他线程执行完任务之后,它才执行;
而CyclicBarrier一般用于一组线程互相等待至某个状态,然后这一组线程再同时执行;
另外,CountDownLatch是不能够重用的,而CyclicBarrier是可以重用的。
7.线程池的优势:(1)降低资源消耗(2)提高响应速度(3)提高线程的可管理型
8.创建线程的方法有继承Thread类,重载run();实现Runnable接口,再重载run();实现Runnable接口更好,因为可以处理同一资源,从而实现资源共享。
9.请简短说明一下你对AQS的理解。
答:AQS其实就是一个可以给我们实现锁的框架。AQS内部有一个核心变量state,是int类型的代表加锁的状态(默认是0)另一个关键变量是用来记录当前加锁的是哪一个线程,初始化为 null;如果线程加锁state会从0变成1。如果线程2来了,会先进入AQS的等待队列,尝试加锁但是如果线程1已经是加锁状态就会失败,然后进入等待加锁(专门放加锁的线程),等线程1
释放锁之后(state状态变成0,加锁线程的变量也变成null),线程2在尝试加锁(state变为1,加锁变量变为线程2)就成功了。
10.简述线程池的运行流程,使用参数以及方法策略
答:主要就是知道线程池核心线程数大小,最大线程数,存储的队列,拒绝策略,空闲线程存货时长。当需要任务大于核心线程数的时候,就可以把任务往存储任务的队列里,当存储队列满了 的话,就开始增加线程池创建的线程数量,如果当线程数量也达到了最大,就开始拒绝策略,比如说记录日志,直接丢弃,或者丢弃最老的任务。