java线程小记

文章更新中未完成

状态总结

大体分为5个状态初始,运行,终结,阻塞,等待 下面是Java中定义的状态

初始

NEW
尚未启动的线程处于此状态。 线程刚刚被创建,等待运行

运行

RUNNABLE
在Java虚拟机中执行的线程处于此状态。 在java中就绪和运行中是一个状态

终结

TERMINATED
已退出的线程处于此状态。 表示此线程的生命周期结束

阻塞

BLOCKED
被阻塞等待监视器锁定的线程处于此状态。 被挂起,线程因为某种原因放弃了cpu timeslice,暂时停止运行。
就像在路上堵着的车

等待

WAITING
正在等待另一个线程执行特定动作的线程处于此状态。 这个等待没有时间需要被手动转换
TIMED_WAITING
正在等待另一个线程执行动作达到指定等待时间的线程处于此状态。 这个等待是有时间限制的
等待就像十字路口等红灯的车

线程的初始状态

当使用new Thread()创建一个新的线程,又还没有开始执行(not yet started)它的时候就处于NEW状态。
线程用start启动才能多线程,如果用run就是个普通方法。
注:一个线程只能被start一次。
start之后,就转换成其他方法了
主要方法 start()

线程的运行状态

这个状态下包含两种状态,一个是可运行的就绪状态,一个是正在运行中的状态,线程运行中使用Thread.yield()当前运行的线程变成可运行状态,可运行的状态会随时被jvm调动变成运行中状态。
当一个线程执行了start方法后,不代表这个线程就会立即被执行,只代表这个线程处于可运行的状态,最终由OS的线程调度来决定哪个可运行状态下的线程被执行。
一个线程一次被选中执行是有时间限制的,这个时间段叫做CPU的时间片,当时间片用完但线程还没有结束时,这个线程又会变为可运行状态,等待OS的再次调度;在运行的线程里执行Thread.yeild()方法同样可以使当前线程变为可运行状态。
主要方法 Thread.yeild()

线程的结束状态

当线程的run()方法完成时,或者主线程的main()方法完成时,我们就认为它终止了。这个线程对象也许是活的,但是,它已经不是一个单独执行的线程。线程一旦终止了,就不能复生。
在一个终止的线程上调用start()方法,会抛出java.lang.IllegalThreadStateException异常。

线程的阻塞与等待状态

在Java的定义中阻塞和等待是两种状态,但是现在大部分的解释都把等待说为阻塞,也就是等待阻塞,也就是start之后既不是运行 RUNNABLE 也不是结束TERMINATED 就是阻塞状态。如果不接受这个理论看网上其他文章会很苦恼的

阻塞与等待的区别

阻塞一般是线程锁被占,等待锁释放就会解除锁住状态
等待一般是调用方法使线程暂停
阻塞:当一个线程试图获取一个内部的对象锁(非java.util.concurrent库中的锁),而该锁被其他线程持有,则该线程进入阻塞状态。
等待:当一个线程等待另一个线程通知调度器一个条件时,该线程进入等待状态。例如调用:Object.wait()、Thread.join()以及等待Lock或Condition。
在java定义中阻塞只是一种状态,而等待代表一种目标,

Java中的阻塞与等待定义

WAITING 等待

等待线程的线程状态 由于调用以下方法之一,线程处于等待状态:
Object.wait没有超时
Thread.join没有超时
LockSupport.park
等待状态的线程正在等待另一个线程执行特定的动作。
例如,已经在对象上调用Object.wait()线程正在等待另一个线程调用该对象上Object.notify()
Object.notifyAll()或。
调用Thread.join()的线程正在等待指定的线程终止。

TIMED_WAITING 有时限的等待

具有指定等待时间的等待线程的线程状态。
线程处于定时等待状态,因为在指定的正等待时间内调用以下方法之一:
Thread.sleep
Object.wait与超时
Thread.join与超时
LockSupport.parkNanos
LockSupport.parkUntil

BLOCKED 阻塞

一个线程的线程状态阻塞等待监视器锁定。
处于阻塞状态的线程正在等待监视器锁定进入同步块/方法,或者在调用Object.wait后重新输入同步的块/方法。
也就是把拿不到锁的线程称为阻塞。
主要方法
除了start(),run()和Thread.yeild()的所有方法

JavaApi定义的线程运行逻辑图

这里的状态遵循java中Thread.State枚举中定义的运行状态
此图为转载图片https://blog.csdn.net/qq_22771739/article/details/82529874
图里有个错误就是join是Thread的方法
多线程解析图

线程同步原理与synchronized

同步的synchronized 代码块的依据就是传入的参数“对象锁”是同一个对象

  • java会为每个object对象分配一个monitor,当某个对象的同步方法(synchronized methods )被多个线程调用时,该对象的monitor将负责处理这些访问的并发独占要求。
  • 当一个线程调用一个对象的同步方法时,JVM会检查该对象的monitor。如果monitor没有被占用,那么这个线程就得到了monitor的占 有 权,可以继续执行该对象的同步方法;如果monitor被其他线程所占用,那么该线程将被挂起,直到monitor被释放。
  • 每个java对象都有一把锁, 当有多个线程同时访问共享资源的时候, 需要Synchronize 来控制安全性, synchronize 分 synchronize 方法 和synchronize块,使用synchronize块时, 一定要显示的获得该对象的锁(如synchronize(object))而方法则不需要。

方法释义

Object类

wait()

导致当前线程等待,直到另一个线程调用该对象的notify()方法或notifyAll()方法。
换句话说,这个方法的行为就好像简单地执行呼叫wait(0) 。
使用wait()不加数字或者加0就会使线程无限期等待,必须手动解除它
native方法

wait(long timeout)

导致当前线程等待,直到另一个线程调用此对象的notify()方法或notifyAll()方法,或指定的时间已过。
有具体等待时间的wait,你也可以提前唤醒 参数单位毫秒

wait(long timeout,int nanos)

导致当前线程等待,直到另一个线程调用此对象的notify()方法或notifyAll()方法,或其他一些线程中断当前线程,或一定量的实时时间。
这种方法类似于一个参数的wait方法,但它允许对放弃之前等待通知的时间进行更精细的控制。
以纳秒为单位的实时数量由下式给出:
1000000*timeout+nanos
在所有其他方面,该方法与一个参数的方法wait(long)相同。
特别是, wait(0, 0)意味着同样的事情wait(0) 。

单位nanos纳秒
timeout纳秒

notify()

唤醒正在等待对象监视器的单个线程。 如果任何线程正在等待这个对象,其中一个被选择被唤醒。
选择是任意的,并且由实施的判断发生。
唤醒的线程将以通常的方式与任何其他线程竞争,这些线程可能正在积极地竞争在该对象上进行同步;
例如,唤醒的线程在下一个锁定该对象的线程中没有可靠的权限或缺点。
唤醒后不是马上会执行,而是进入就绪状态和等待系统调度

notifyAll()

唤醒正在等待对象监视器的所有线程。
唤醒后不是马上会执行,而是进入就绪状态和等待系统调度。

Thread类

join()

等待这个线程结束。使线程进入等待状态,或者称为‘等待阻塞’
内部用的wait实现的,只有唤醒后才能继续运行

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值