5分钟系列之-java内存模型与线程(三、java与线程)

8 篇文章 0 订阅

java与线程

1.线程的实现

  实现线程主要三种方式:使用内核线程实现、使用用户线程实现、使用用户线程加轻量级进程混合实现

1.1使用内核线程实现

  内核线程(Kernel-Lvel Thread,KLT)就是直接由操作系统内核支持的线程,这种线程由内核完成线程切换,内核通过操作调度器对线程进行调度,并负责将线程映射到各个处理器上。程序一般不会直接使用内核线程,而是使用内核线程的一种高级接口-轻量级进程(Light Weight Process.LWP),轻量级进程就是我们通常意义上所讲的线程,每个轻量级进程都有一个线程支持,因此只有先支持内核线程才能支持轻量级进程,轻量级进程与内核线程之间是一对一的线程模型。
在这里插入图片描述

优点:
  每个轻量级进程都成为一个独立调度单元,即使一个轻量级进程在系统调度中阻塞了,也不会影响整个进程继续工作。
缺点:
  1.由于是基于内核线程实现,所以各种线程操作,如创建、析构及同步都需要进行系统调用。而系统调用的代价相对较高,需要在用户态和内核态来回切换。

 2.每个轻量级进程都需要一个内核线程支持,因此轻量级进程需要消耗内核组员,因此一个系统支持轻量级进程的数量是有限的。

1.2使用用户线程实现

  广义上讲,一个线程只要不是内核线程,就可以认为是用户线程,因此,轻量级进程也属于用户线程。
狭义上讲,用户线程是指完全建立在用户空间的线程库上,系统内核不能感知线程存在的实现。这种线程不需要内核的帮助,不需要切换到内核态,因此操作是非常快速且低消耗的,也可以支持更多的线程数。
在这里插入图片描述

优点:
  不需要内核支援;
缺点:
  由于没系统内核的支援,所有的线程操作都要用户程序自己处理,而需要处理的问题非常多且复杂,因此现在使用用户线程的越来越少了。

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

  这种方式用户线程还是建立在用户空间中,因此可以用户用户线程的开销低,数量多,支持大规模并发的优点,又可以使用轻量级进程作为用户线程和内核线程之间的桥梁,使用内核提供的线程调度功能及处理器映射,用户线程的系统低啊用通过轻量级进程完成还能降低整个进程被阻塞的风险。在这种混合模式中,用户线程与轻量级进程的数量比是不定的,即位N:M的关系。
在这里插入图片描述

1.4Java线程的实现

  Java线程在jdk 1.2之前是使用用户线程来实现的,在jdk 1.2中,线程模型替换位基于操作系统远程线程模型来实现。因此在目前的JDK版本中,操作系统支持怎样的线程模型,很大程度上决定了Java虚拟机线程是怎样映射的,这点在不同平台上无法达成一致。

2.Java线程调度

  线程调度主要分为两种方式,协同是调度和抢占式调度。

2.1协同式线程调度

  协同是调度需要线程执行完主动通知切换到另一个线程上;
优点:
  这种实现方式最大的好处是实现简单,切换操作对自己是可知的,因此没有线程同步问题;
缺点:
  相当不稳定,一个进程坚持不让出cpu就回导致整个系统瘫痪。

2.2抢占式线程调度

  线程讲又系统进行调度与分配执行时间,无法预知自己的执行。
优点:
  不会因为一个线程有问题导致正系统崩溃,还可以杀死有问题的进程;
缺点:
  实现复杂,需要考虑同步问题,java使用的就是这种方式。

2.2.1线程优先级:

  线程的优先级不态靠谱,因为java的线程是通过映射到系统原生线程上实现的,所以调度最终取决与操作系统,不同操作系统拥有的有限即数量是不一样的,因此会导致优先级比java少的操作系统会有多个不同的java优先级映射到同一个等级。除此之外还可能被操作系统自行改变,比如windows操作系统有个优先级推进器的功能,会给“勤奋努力”的线程分配更多的资源。

2.2.2状态转换

  java语言定义了5种线程状态,任意时间点,一个线程只能有其中的一种状态;

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

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

  ■无限期等待(Waiting):处于这种状态的线程不会被分配CPU执行时间,他们要等待被其他线程现实的唤醒。以下方法会让线程陷入无限等待状态。○
    ○没有设置TimeOut参数的Object.wair()方法。
    ○没有设置TimeOut参数的Thread.join()方法。
    ○LockSupport.park()方法。

  ■限期等待(Timed Waiting):处于这种状态的线程也不会被分配CPU执行时间,不过无须等待被其他线程显式地唤醒,在一定时间之后它们会由系统自动唤醒。以下方法会让线程进入限期等待状态:
    ○Thread.sleep()方法。
    ○设置了 Timeout 参数的 Object.wait()方法。
    ○设置了Timeout 参数的Thread.join()方法。
    ○LockSupport.parkNanos()方法。
    ○LockSupport.parkUntil()方法。

  ■阻塞(Blocked):线程被阻塞了,“阻塞状态”与“等待状态”的区别是:“阻塞状态”在等待着获取到一个排他锁,这个事件将在另外一个线程放弃这个锁的时候发生;而“等待状态”则是在等待一段时间,或者唤醒动作的发生。在程序等待进入同步区域的时候,线程将进入这种状态。
  ■结束(Terminated):已终止线程的线程状态,线程已经结束执行。

上述5种状态在遇到特定事件发生的时候将会互相转换,它们的转换关系如图
在这里插入图片描述


公众号同步更新,欢迎订阅

​​​​ 在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值