JAVA线程实现原理、线程状态

JAVA线程现在的实现是基于操作系统原生线程模型来实现的。因此,现在操作系统支持怎样的线程模型,在很大程度上决定了JAVA虚拟机的线程是怎样映射的。这点在不同的平台上没有办法达成一致。

对于Sun JDK来说,它的Windows版和Linux版都是使用一对一的线程模型实现的,一条Java线程就映射到一条轻量级进程中,因为Windows和Linux系统提供的线程模型就是一对一的。

Java线程调度

线程调度的方式有协同式线程调度和抢占式线程调度。

协同式线程调度

如果使用协同式调度的多线程系统,线程的执行时间由线程本身控制,线程把自己的工作执行完了以后,要主动通知系统切换到另外一个线程上。其最大的好处是实现简单,而且由于线程要把自己的事情干完后才会进行线程切换,,切换操作对线程自己是可知的,所以没有什么线程同步问题。缺点是线程执行时间不可控,如果一个线程编写有问题,可能会导致到线程一直阻塞在那里。

抢占式线程调度(JAVA采用的线程调度方式)

使用抢占式调度的多线程系统,每个线程都将由系统来分配执行时间,线程的切换不由线程本身来决定。因此线程的执行时间是可控的,也不会因为一个线程导致整个进行阻塞。

虽然Java线程是通过系统调度自动完成的,但我们可以”建议“系统给某些线程多分配一点执行时间,另外一些线程则少分配一点——此操作可以通过设置线程优先级来完成。Java语言共有10个级别的线程优先级。优先级越高的线程越容易被系统选择执行。不过,线程优先级并不是很靠谱,因为Java线程是通过映射到系统的原生线程上来实现,所以线程调度最终还是取决于曹祖系统。虽然很多操作系统都提供了线程优先级的概念,但是并不见得能与Java线程优先级一一对应。比java线程优先级多的还好说,中间可以留一些空位,但比java线程优先级少的,就不得不出现几个优先级相同的情况了(windows中线程优先级只有7种)。

Thread.MAX_PRIORITY; //最高优先级    10
Thread.NORM_PRIORITY; // 默认优先级  5
Thread.MIN_PRIORITY; // 最低优先级   1

Java线程状态转换

Java定义了6种线程状态,在任意一个时间点,一个线程只能有且只有其中一种状态。

新建(NEW):创建后尚未启动的线程处于这种状态。(为start)

运行(Runable):Runable包括了操作系统线程状态中的Running和Ready,也就是处于此状态的线程有可能正在执行,也有可能正在等待着CPU为它分配执行时间。

无限期等待(Waiting):处于这种状态的线程不会被分配CPU执行时间,它们要等待被其他线程显式地唤醒。

  • 没有设置Timeout参数的Object.wait()方法;
  • 没有设置Timeout参数的Thread.join()方法;
  • LockSupport.park()方法;

限期等待(Timed Waiting):处于这种状态的线程也不会被分配CPU执行时间,不过无须等待被其他线程显式地唤醒,在一定时间之后它们会由系统自动唤醒。

  • Thread.sleep()方法;
  • 设置了Timeout参数的Object.wait()方法;
  • 设置了Timeout参数的Thread.join()方法;

阻塞(Blocked):线程被阻塞了,“阻塞状态”与”等待状态“的区别是:”阻塞状态“在等待获取一个排它锁,这个事件将在另外一个线程放弃这个锁的时候发生;而”等待状态“则是在等待一段时间,或者唤醒动作的发生。

  • 在程序等待进入同步区域的时候,线程将进入这种状态;

结束(Terminated):已终止线程状态,线程已经结束运行。

线程的实现方式

使用内核线程实现

内核线程(KLT)就是直接由操作系统内核支持的线程,这种线程由内核来完成线程切换。内核通过调度器对线程进行调度,并负责将线程的任务映射到各个处理器上。

程序一般不会直接去使用内核线程,而是去使用内核线程的一种高级接口——轻量级进程(LWP),轻量级进程就是我们通常意义上讲的线程,由于每个轻量级进程都由一个内核线程支持,因此只有先支持内核线程,才能有轻量级进程,这种轻量级进程与内核线程之间1:1的关系称为一对一线程模型。

由于内核线程的支持,每个轻量级进程都成为一个独立的调度单元,即使有一个轻量级进程在系统调用中阻塞了,也不会影响整个进程继续工作,但是轻量级进程具有它的局限性:首先,由于是基于内核线程实现的,所以各种线程操作,如创建等,都需要进行系统调用。而系统调用代价较高,需要在用户态和内核态中来回切换;其次每个轻量级进程都需要有一个内环线程支持,因此轻量级进程需要消耗一定的内核资源(内核线程的栈空间),因此一个系统支持轻量级进程的数量是有限的。

使用用户线程实现

用户线程指完全建立在用户空间的线程库上,系统内核不能感知线程存在的实现,用户线程的建立、同步、调度完全在用户态中完成,不需要内核的帮助,也不需要切换到内核态,因此操作是非常快速且低消耗的。这种进程与用户线程1:N的关系称为一对多的线程模型。使用用户线程优势是不需要内核支持,缺点也是由于没有内核支持,线程的操作都要由用户自己处理。而且由于操作系统只把处理器资源分配给进程,如”阻塞处理“等问题都将难以解决。

使用用户线程加轻量级进程混合实现

在这种情况下,既有用户线程,也存在轻量级进程。用户线程完全建立在用户空间中,因此用户线程的创建、同步等操作依然廉价并且可以支持大规模用户线程并发。而操作系统提供支持的轻量级进程则作为用户线程和内核线程之间的桥梁,这样可以使用内核提供的线程调度功能,并且用户线程的系统调用要通过轻量级进程来完成,大大降低了整个进程被完全阻塞的风险。此种情况下,用户线程与轻量级进程的数量比是不定的,即N:M的关系,即多对多模型。

参考:https://blog.csdn.net/weixin_42294335/article/details/80933754

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值