Java编程思想拾遗(15) 并发

注:并发涵盖的知识点较多,本专栏侧重于梳理与拾遗,所以本文没有进行详细的知识点介绍与demo演示哈,不过笔者后面有可能会出一期JDK源码阅读专栏,里面会重点关注并发相关的类库

如果你有一台多处理器的机器,那么就可以在这些处理器之间分布多个任务,从而极大地提高吞吐量,但是并发通常是指提高运行在单处理器上的程序的性能(或许这就是所谓的并行和并发的概念区别)。

如果使用并发来编写程序,那么当一个任务阻塞时,程序中的其他任务还可以继续执行,因此这个程序整体就可以继续保持向前执行。单处理器系统中性能提高的常见示例是事件驱动的编程,通过创建单独的执行线程进行事件监听,可以避免所有任务都周期性地检查事件输入,即使这个线程在大多数时间都是阻塞的,程序依然可以保证具有一定程度的可响应性。

线程调度

Java在顺序型语言的基础上提供对线程的支持,与在多任务操作系统中分叉外部进程不同,线程机制是在由执行程序表示的单一进程中创建任务,这种方式产生的一个好处是操作系统的透明性,这对Java而言,是一个重要的设计目标。

Java的线程机制是抢占式的,这表示调度机制会周期性地中断线程,将上下文切换到另一个线程,从而为每个线程都提供时间片,使得每个线程都会分配到数量合理的时间去驱动它的任务(注意,这里说明的是线程间的切换,而不是线程内部排队任务的切换,该老实排队的还是得老实排队)。

线程的优先级将该线程的重要性传递给调度器,尽管CPU处理现有线程集的顺序是不确定的,但是调度器将倾向于让优先级高的线程来执行,然而这并不意味着优先级较低的线程将得不到执行,它们仅仅是执行的频率较低。

如果知道已经完成了在run()方法中循环一次迭代中所需的工作,就可以通过调用yield()方法给线程调度一个暗示:我的工作已经做得差不多了,可以让别的线程使用CPU了,不过这只是一个暗示,没有任何机制保证它将会被采纳,对于任何重要的控制都不能依赖于yield()。

后台daemon线程,是指在程序运行时在后台提供服务的线程,当所有的非后台线程结束时,程序也就终止了,同时会杀死进程中的所有后台线程(此时finally是不会被保证的,毕竟连指令都不执行了),反过来说,只要有任何非后台线程还在运行,程序就不会终止。

线程状态

一个线程可以处于以下四种状态之一:

  1. 新建(New):当线程被创建时,它只会短暂地处于这种状态,此时它已经分配了必需的系统资源,并执行了初始化。此刻线程已经有资格获得CPU时间了,之后调度器将把这个线程转变为可运行状态或阻塞状态。
  2. 就绪(Runnable):在这种状态下,只要调度器把时间分配给线程,线程就可以运行。也就是说,在任意时刻,线程可以运行也可以不运行,这不同于阻塞和死亡状态。
  3. 阻塞(Blocked):线程能够运行,但有某个条件阻止它的运行,当线程处于阻塞状态时,调度器将忽略线程,不会分配给线程任何CPU时间,直到线程重新进入了就绪状态,它才有可能执行操作。
  4. 死亡(Dead):处于死亡或者终止状态的线程将不再是可调度的,并且再也不会得到CPU时间,它的任务已结束,或不再是可运行的。任务死亡的通常方式是从run()方法返回,但是任务的线程还可以被中断。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享