基本概念 进程 所谓进程就是运行在操作系统的一个任务,进程是计算机任务调度的一个单位,操作系统在启动一个程序的时候,会为其创建一个进程,JVM就是一个进程。进程与进程之间是相互隔离的,每个进程都有独立的内存空间。 计算机实现并发的原理是:CPU分时间片,交替执行,宏观并行,微观串行。同理,在进程的基础上分出更小的任务调度单元就是线程,我们所谓的多线程就是一个进程并发多个线程。 线程 在上面我们提到,一个进程可以并发出多个线程,而线程就是最小的任务执行单元,具体来说,一个程序顺序执行的流程就是一个线程,我们常见的main就是一个线程(主线程)。 线程的组成 想要拥有一个线程,有这样的一些不可或缺的部分,主要有:CPU时间片,数据存储空间,代码。 CPU时间片都是有操作系统进行分配的,数据存储空间就是我们常说的堆空间和栈空间,在线程之间,堆空间是多线程共享的,栈空间是互相独立的,这样做的好处不仅在于方便,也减少了很多资源的浪费。代码就不做过多解释了,没有代码搞个毛的多线程。 线程的创建和启动 传统创建线程有两种方式
JDK1.5 线程池 ExecutorService(线程池 interface) Callable对象 从以上这段代码我们可以看到很多不一样的地方,首先在Callable对象中是可以抛出异常的,其次有返回值,在这个基础上也就引出了一个新的问题,如果接收该线程的对象?JDK1.5中也给出了解决的方法是Future对象. 启动线程 在这里我们需要明白,上面两种方式并不会让我们得到真正的线程,只是得到了线程对象,只有启动线程,才算得到了真正的线程。 通过执行start()方法能够启动一个线程,但是启动线程并不是立即执行,成功启动的线程会处于就绪状态,什么时候执行需要等到拿到时间片之后。 线程的分类 用户线程和守护(Daemon)线程。 守护线程:守护线程会一直运行,直到其他非守护线程都结束的时候,才会结束。有一个典型的守护线程就是:垃圾回收线程,和虚拟机共存亡,直到虚拟机中没有任何线程的时候虚拟机关闭的时候才会终止,简单说就是虚拟机在,它就在,虚拟机亡便亡。 线程的状态 上面我们提到过,一个线程在启动之后不会立马执行,而是处于就绪状态(Ready),就绪状态就是线程的状态的一种,处于这种状态的线程意味着一切准备就绪, 需要等待系统分配到时间片。为什么没有立马运行呢,因为同一时间只有一个线程能够拿到时间片运行,新线程启动的时候让它启动的线程(主线程)正在运行,只有等主线程结束,它才有机会拿到时间片运行。 **线程的状态:**初始状态(New),就绪状态(Ready),运行状态(Running)(特别说明:在语法的定义中,就绪状态和运行状态是一个状态Runable),等待状态(Waitering),终止状态(Terminated) RUNNABLE),等待状态(Waitering),终止状态(Terminated) 初始状态(New) 线程对象被创建出来,便是初始状态,这时候线程对象只是一个普通的对象,并不是一个线程。 Runable **就绪状态(Ready):**执行start方法之后,进入就绪状态,等待被分配到时间片。 **运行状态(Running):**拿到CPU的线程开始执行。处于运行时间的线程并不是永久的持有CPU直到运行结束,很可能没有执行完毕时间片到期,就被收回CPU的使用权了,之后将会处于等待状态。 等待状态(Waiting) 等待状态分为有限期等待和无限期等待,所谓有限期等待是线程使用sleep方法主动进入休眠,有一定的时间限制,时间到期就重新进入就绪状态,再次等待被CPU选中。 而无限期等待就有些不同了,无限期并不是指永远的等待下去,而是指没有时间限制,可能等待一秒也可能很多秒。至于进入等待的原因也不尽相同,可能是因为CPU时间片到期,也可能是因为一个比较耗时的操作(数据库),或者主动的调用join方法。 wait和sleep的区别
阻塞状态(Blocked) 在我看来,阻塞状态实际上是相当特殊的待机状态。 其他等待线程正在等待其他线程等待使用CPU的权利。 线程仍然卡住。 即使处理器没有处于自由的状态,它不仅适用于使用主锁标记CPU的权利,而且也适用锁标记。 (锁定在下一节:线程同步) 等待和阻塞的区别
终止线程(Terminated) 已经终止的线程会处于该种状态。 |
|
来自: Frank_Chia > 《JAVA》