Java线程知识总结(一):基础线程知识

1、线程状态

Java线程有6中状态,分别是:NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING,以及TERMINATED
其中线程状态切换图如下:线程状态切换图

  1. 线程start后,从NEW -> RUNNABLE;
  2. 如果线程运行需要锁,则等待锁时,线程状态为BLOCKED,获取到锁后BLOCKED -> RUNNABLE;
  3. 线程调用wait之后,如果有设定超时时间则RUNNABLE -> TIMED_WAITING,
    否则RUNNABLE -> WAITING;
  4. WAITING状态的线程被notify后,WAITING -> RUNNABLE;
  5. TIMED_WAITING状态线程,在被notify或超时时,TIMED_WAITING -> RUNNABLE;
  6. 线程任务结束,RUNNABLE -> TERMINATED.

2、线程终止

线程终止方法:

  • stop:强制终止线程,并且清除监控器锁的信息,JDK中不建议使用
    不管是否线程是否占用锁,都会强制终止,所以可能会导致线程不安全的问题。
  • interrupt:不会强制终止,保证线程安全
    如果目标线程在调用wait,join,或者sleep方法时被阻塞,interrupt会立即生效,并抛出
    InterruptedException异常。可以通过捕获InterruptedException异常,进行相应的业务处理
    如果目标线程时被I/O或者NIO的Channel所阻塞,同样,I/O操作会被中断,或者返回特殊异常值。达到终止线程的目的。
  • 使用标志位实现线程终止
    在这里插入图片描述

3、线程通信

  • suspend & resume
    已弃用。原因:容易引发死锁
    同步代码块中使用,suspend调用后,不会释放锁 -> 死锁
    suspend在resume后调用 -> 死锁
  • wait & notify
    wait和notify的调用顺序非常重要,如果wait在notify后进行调用,则线程会一直处在WAITING状态。
    wait,notify,notifyAll只能由同一对象锁的持有者线程调用,也就是要写在同步块里面,且调用后会释放锁。如果不在同步块中使用wait,notify和notifyAll会抛出IllegalMonitorStateException异常。
  • park & unpark
    LockSupport工具类提供的方法。令牌机制。
    park等待令牌,unpark提供令牌,令牌只能存在一个
    不要求park和unpark方法的调用顺序。多次调用unpark之后,再调用park,线程会直接运行。
    但不会叠加,也就是说,多次调用park方法,第一次会拿到令牌,直接运行,后续调用会进行等待。
    park/unpark不是基于锁监视器实现的,所以如果在同步代码块中,不会释放锁 -> 死锁
    unpark指定到线程
Thread thread = new Thread(new Runnable() {
		public void run() {
		LockSupport.park();
	}
});
thread.start();
LockSupport.unpark(thread);  

重点提醒:
伪唤醒: 线程并非因为notify、notifyAll、unpark等api调用而唤醒,是更底层原因导致的
官方建议应该在循环中检查等待条件,原因是处于等待状态的线程可能会受到错误警报和伪唤醒,如果不在循环中检查等待条件,程序就会在没有满足结束条件的情况下退出
在这里插入图片描述

4、线程私有

线程封闭:封闭对应开放

  • 开放:共享数据,共享变量,会涉及线程安全,以及同步数据的问题
  • 封闭:数据封闭在各自的线程之中,就不需要同步,这种通过将数据封闭在线程中而避免使用同步的技术成为线程封闭。在并发模式下是线程安全的。

线程封闭具体的体现有:ThreadLocal,局部变量

  • ThreadLocal
    ThreadLocal var = new ThreadLocal()
    线程级别的变量,会自动在每一个线程上创建一个T的副本,副本之间彼此独立,不相互影响。在并发模式下是绝对安全的变量
    可以用ThreadLocal存储一些参数,一遍在线程中多个方法中使用,用来替代方法传参的问题
    可以理解为JVM维护了一个Map<Thread, T>,每个线程要用到这个变量T的时候,用当前的线程去Map中取,取出来的都是不一样的。
  • 局部变量
    局部变量的固有属性之一就是封闭在线程中的。
    它们位于执行线程的栈中,其他线程无法访问这个栈。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值