Java高效并发(二)----JAVA线程实现、调度、状态

进程与线程的区别

进程:CPU资源分配的最小的单位,由进程的各个线程共享

线程:cpu执行调度的最小单位,优点充分利用CPU资源

操作系统线程的实现

主流的操作系统都提供了线程的实现

(1)内核线程实现

内核线程(KLT)就是由操作系统内核直接支持的线程,内核通过操纵调度器对线程进行调用,程序不直接与内核线程接触而是通过一种高级接口轻量级进程(LWP),它与内核线程一一对应,这就是我们常说的线程,程序和内核线程通过轻量级进程联系起,所以我们常说线程是CPU调度的最小单位,但是这样的局限性就是每次线程操作都需要从用户态到内核态的转化,代价高,而且由于一一对应的关系,轻量级线程数量肯定有限的,受制于内核线程的数量。一对一

(2)用户线程实现

一个线程不是内核线程就是用户线程,由用户线程实现也就是线程的同步,调度销毁都在用户态进行,没有操作系统支持,不能保证正确性。多对一

(3)使用用户线程加轻量级线程实现

多对多

Java线程实现

java线程实现基于操作系统原生线程模式来实现,对于SUN JDK windows版本和linux版本都是使用一对一的线程模型来实现,就是一条java线程就映射到一条轻量级进程一种,也就是说现在的Java中线程的本质,其实就是操作系统中的线程

Java线程调度

现在操作系统一般采用采用抢占式线程调度,抛弃了协同式线程调度,抢占式调度由操作系统控制线程占用CPU的时间,那么线程的执行时间是可控制的。虽然java的线程调度是系统自己完成的,我们可以通过设置线程的优先级来给系统一些“建议”。但是也不靠谱,因为java线程是要映射到操作系统的原生线程中的,我们知道在java中一共有10个等级的优先级,虽然操作系统也有优先级的概念但是不能一一对应,windows有六个优先级少于java,那么java线程的优先级映射到操作系统,必然要有优先级更改为相同的。而且操作系统在调度线程的时候也会根据“优先级推进器”来改变要调度的线程。

所以java中我们不能根据优先级判断处于ready的线程会先执行哪一个

Java线程状态

新生态:一个线程被创建还没有调用start()方法

运行态:调用start()方法

就绪状态:状态处于就绪队列,等待CPU调度

在java里运行态和就绪状态统称为Runnable状态

无限期等待状态:线程执行了没有timeout参数的wait()方法或者执行了没有timeout参数的join()或者LockSupport.park()方法,处于这种状态必须等待被其他线程唤醒,执行notify()/notifyall(),才会进入就绪状态

限期等待状态:线程执行了有timeout参数的wait()方法,或者执行了有timeout参数的join()或者执行sleep()方法等,等时间一到自己进入就绪状态

阻塞状态:区别于等待状态,处于阻塞状态的线程正在等待一个排它锁资源

结束状态:run方法结束线程结束执行

方法区别

 run():实现线程的方法,线程体,线程调用run()方法相当于一个普通方法

start():启动线程

sleep(time):让线程暂停一定的时间,如果线程拥有锁资源,不会释放

wait():有参数或者无参数,停下线程,释放锁资源

notify()/notifyall():唤醒线程。这个方法和wait方法必须在synchronized同步块中使用,调用这两个方法的对象得先获得锁。所以被唤醒的线程醒了之后不立即执行,会继续等待获得对象的锁(监视器)

join():有参数或者无参数,调用jion的线程执行,也就是阻塞掉别的线程,等待自己执行完,让别的线程再开始执行,把两个线程合并一起

Java高效并发(二)----JAVA线程实现、调度、状态_第1张图片

yield():暂停当前正在执行的线程对象,并执行其他线程。在多线程的情况下,由CPU决定执行哪一个线程,而yield()方法就是暂停当前的线程,让给其他线程(包括它自己)执行,具体由谁执行由CPU决定

 

 

 

 

你可能感兴趣的:(java高并发)