Java并发之线程
讨论并发,大多数都与线程脱不开关系。本文将对从线程的特点、多线程优势以及线程状态和实现等几个方面讲解Java线程,同时讲解Java线程在虚拟机中如何实现。
01
线程的特点和实现
说到线程,首先要谈到进程;进程是操作系统资源分配和调度的基本单位,即运行起来的程序。毕竟进程是粗粒度的单位,为了更好地量化程序,引入了线程的概念。
线程,即轻量级进程,是CPU调度和分配的单位;在一个进程中的线程共享进程资源,又可以独立调度。在操作系统中实现线程的实现方式有3中方式:
1.使用内核线程实现
2.使用用户线程实现
3.使用用户线程加轻量级进程混合实现
使用内核线程实现:内核线程就是直接由操作系统内核支持的线程,这种线程由内核来完成线程切换。用户程序不能直接使用内核线程,而是使用内核线程的一种高级接口-轻量级进程,即我们通常意义说的线程。每一个轻量级进程都是由一个内核线程支持的,即轻量级进程与内核线程之间为1:1关系。需要注意的是,内核线程需要系统调用,代价较高,且需要消耗内核资源。
用户线程实现:一个线程只要不是内核线程,可以认为用户线程。进程与用户线程之间的是1:N的关系被称为一对多的线程模型,用户线程的优势在于不需要系统内核,劣势在于线程的创建、切换和调度都是需要用户程序考虑的问题。
使用用户线程加轻量级进程混合实现:这是一种将内核线程与用户线程一起使用的实现方式。这种模式下,即存在用户线程,也存在轻量级进程。不同于其他实现,这种混合模式创建廉价,并且可以支持大规模的用户线程并发。
02
多线程优势
那么,我们什么需要使用多线程程序呢?换句话说,多线程程序的好处是什么呢?
其实,多线程程序的优势有这几点:
1.提高程序效率
2.发挥多处理器优势
3.更简易的编程模型
多线程可以大大提高程序的效率,在多个线程同时处理事件时,可以拆分任务将多个线程处理。
当然,现在计算机的CPU都是多核的,那么如果仅仅只是发挥了一个核来处理,就必然造成了一些处理器的浪费。
还有就是编程模型,我们可以将I/O事件和逻辑业务分离开来进行处理,不用阻塞等待,编程逻辑更加简单。
03
Java线程实现
JDK中,Java线程模型是基于操作系统原生线程模型来实现的。由于Windows和Linux系统提供的线程模型是1对1,即在这两个系统中,Java的一个线程对应系统的一个线程。
当然,在Java API中实现Java线程的方式主要是继承Thread类和实现Runnable接口。我们只需要在这两个类的方式中将业务逻辑写在run方法中即可。
这里需要尤其注意线程的两个方法,Sleep和Yield方法。Thread.sleep导致线程将会睡眠一定的时间,当然睡眠时间取决于方法参数时间和系统定时器和调度器的经度和准确度。线程不会让出该线程持有的锁或者管程(即监视器),当然线程执行的恢复取决于处理器得到调度和利用率来执行线程。
Thread.yield方法只是将CPU让出,线程并没有进入阻塞队列而是进入就绪状态,线程只要调用Sleep方法就会进入阻塞队列,不管sleep传入的参数是否是0.
以上两个方法都是没有任何同步语义的。特别地,编译器没有在调用以上两个方法之前将写缓存写入到共享缓存中,下面举个例子:
字段done是一个非volatile boolean类型,编译器将会从线程工作空间中读取缓存的值,这里线程将永远也不会终止,即便另一个线程改变了done的值。
while(!this.done)
{
Thread.sleep(1000);
}
04
Java线程转换
Java语言定义了5种状态,在任意一个时间点,一个线程只能有有且只有其中的一种状态:
新建:创建见后尚未启动的线程处于这种状态。
运行:线程处于执行状态
等待:线程的CPU时间片使用完了、
阻塞:线程等待某种状态的发生
结束:线程终止。
05
总结
重点需要了解的Java线程的实现方式和线程的几个重要方法,例如sleep和yield方法。当然,我们需要了解多线程的优势和好处,同时也要明白线程的状态状态,这在多线程编码时了然于胸。
▼
往期精彩回顾
▼
点击二维码,关注我们
15
好看你就点点我