线程相关总结

1.线程的5种状态如何切换


线程的5种状态:新建、就绪、运行、阻塞、死亡。


切换:
sleep() : 让当前线程暂停一段时间;


yield() : 该方法与sleep()类似,只是不能由用户指定暂停多长时间,并且yield()方法只能让同优先级的线程有执行的机会。


join() : Thread的非静态方法join()让一个线程B“加入”到另外一个线程A的尾部。在A执行完毕之前,B不能工作。join() 方法主要是让调用该方法的thread完成run方法里面的东西后,再执行join()方法后面的代码


扩展:


Object类的wait(), notify(), notifyAll()方法:


wait()
释放占有的对象锁,线程进入等待池,释放cpu,而其他正在等待的线程即可抢占此锁,获得锁的线程即可运行程序。而sleep()不同的是,线程调用此方法后,会休眠一段时间,休眠期间,会暂时释放cpu,但并不释放对象锁。也就是说,在休眠期间,其他线程依然无法进入此代码内部。休眠结束,线程重新获得cpu,执行代码。wait()和sleep()最大的不同在于wait()会释放对象锁,而sleep()不会!
 
notify()
该方法会唤醒因为调用对象的wait()而等待的线程,其实就是对对象锁的唤醒,从而使得wait()的线程可以有机会获取对象锁。调用notify()后,并不会立即释放锁,而是继续执行当前代码,直到synchronized中的代码全部执行完毕,才会释放对象锁。JVM则会在等待的线程中调度一个线程去获得对象锁,执行代码。需要注意的是,wait()和notify()必须在synchronized代码块中调用。


notifyAll()
会唤醒所有等待(对象的)线程,尽管哪一个线程将会第一个处理取决于操作系统的实现。






2.线程是否可以重复启动,会有什么后果?


单一线程不能重复启动,否则报IllegalThreadStateException


扩展:


Thread.interrupt()方法不会中断一个正在运行的线程。这一方法实际上完成的是,在线程受到阻塞时抛出一个中断信号,这样线程就得以退出阻塞的状态。更确切的说,如果线程被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞,那么,它将接收到一个中断异常(InterruptedException),从而提早地终结被阻塞状态。






3.synchronized 和 Lock 的区别


ReentrantLock 相对于固有锁synchronized,在某些vm版本上提供了比固有锁更高的性能,提供了更丰富的锁特性,比如可中断的锁,可等待的锁,平等锁以及非块结构的加锁。从代码上尽量用固有锁,jvm会对固有锁做一定的优化,并且代码可维护和稳定。只有在需要ReentrantLock的一些特性时,可以考虑用ReentrantLock实现。


另外,在并发量比较小的情况下,使用synchronized是个不错的选择,但是在并发量比较高的情况下,其性能下降很严重,此时ReentrantLock是个不错的方案。






4.悲观锁、乐观锁,如何自己实现一个乐观锁?


乐观锁是假设我已经拿到锁,悲观所是我必须拿到锁,前者用CAS,后者用Mutex。
利用CAS原理即可实现乐观锁,简单思路就是-比较和交换。






5.线程的实现方式


继承Thread类


实现Runnable接口


实现Callable<>接口(配合FutureTask类,用Thread类启动,Callable接口的call()方法带返回值)


另外:使用Executor framework (这会创建一个线程池)


采用继承Thread类方式:
1 优点:编写简单,如果需要访问当前线程,无需使用Thread.currentThread()方法,直接使用this,即可获得当前线程。
2 缺点:因为线程类已经继承了Thread类,所以不能再继承其他的父类。不能够很好的体现数据共享。
采用实现Runnable接口方式:


1 优点: 线程类只是实现了Runable接口,还可以继承其他的类。 可以多个线程共享同一个目标对象,所以非常适合多个相同线程来处理同一份资源的情况。能够很好的体现数据共享。
2 缺点:编程稍微复杂,如果需要访问当前线程,必须使用Thread.currentThread()方法。






6.线程池拒绝策略


ThreadPoolExcutor.AbortPolicy() 线程池满时,抛出异常,默认操作
ThreadPoolExcutor.CallerRunsPolicy() 线程池满时,用调用者所在线程来运行任务
ThreadPoolExcutor.DiscardOldersPolicy() 线程池满时,不处理,直接丢掉丢弃队列里最旧的一个任务,并执行当前任务
ThreadPoolExcutor.DiscardPolicy() 线程池满时,不处理,直接丢掉






7.ThreadLocal 应用场景


在多线程环境下使用SimpleDateFormat,以及进行数据库连接关闭操作等。


扩展:ThreadLocal就是创建成员变量副本,Thread类中有一个ThreadLocal.ThreadLocalMap threadLocals成员变量,用以保存本地成员变量副本。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值