多线程编程

这是《Java8编程参考官方教程》第11章的笔记。

基于进程的多任务处理是”大局“,基于线程的多任务处理是”细节“。
虽然Java使用基于多进程的多任务环境,但是基于多进程的多任务处理不是由Java控制的。不过,基于多线程的多任务处理是由Java控制的。
多线程实现最大限度利用系统功能的一种重要方式是使空闲时间保持最少。

Java线程模型:运行状态(running)、挂起(suspended)、恢复(resumed)、阻塞(blocked)、终止。
线程优先级:线程的优先级体现在决定何时从一个运行的线程切换到下一个。Java定义的规则如下:
    1. 线程自愿放弃控制;
    2. 线程被优先级更高的线程取代。这称为抢占式多任务处理(preemptive multitasking)。
如果两个线程优先级相等,在windows下他俩以循环方式自动获得CPU资源。对于其他系统,优先级相等的线程必须自愿地向其他线程放弃控制权,否则其他线程不能运行。
同步:在Java里,每个对象都有自己的隐式监视器。如果调用对象的同步方法,就会自动进入对象的隐式监视器。Java语言本身内置了同步支持。
消息传递:通过调用所有对象都具有的预先定义的方法。

主线程:
  1. 其他子线程都是从主线程产生的;
  2. 通常,主线程必须是最后才结束的线程,因为它要执行各种关闭动作。


创建线程:
  1. 实现Runnable接口;
  2. 扩展Thread类本身。
哪种方式更好:如果不重写Thread类的其他方法,创建子线程的最好方式可能是简单的实现Runnable接口。

判断子线程是否结束:
  1. isAlive();
  2. join()。此方法等待线程结束。


线程优先级:
  1. MIN_PRIORITY:1
  2. MAX_PRIORITY:10
  3. NORM_PRIORITY:5
不同的Java实现对于任务调度可能有很大的区别。如果线程依赖于抢占式行为,而不是协作性的放弃CPU,那么精彩会引起不一致性,使用Java实现可预测、跨平台行为的最安全方法是使用资源放弃CPU控制权的线程。

同步:
  1. 使用同步方法:在方法定义的前面添加关键字synchronized。这样当一个线程使用此方法时,会阻止其他线程进入该方法。
  2. synchronized语句:
                                        synchronized(objectReference) {}
                                        objcetReference是对同步对象的引用,方法代码块内是对objectReference对象的成员方法的调用。


线程间通信:为了避免轮询检测,Java通过wait()、notify()、notifyAll()方法,提供了一种巧妙的进程间通信机制。这些方法在Object中是作为final实现的,因此所有类都具有这些方法。
当两个线程循环依赖一对同步对象时,会发生死锁。

挂起、恢复与停止线程:Java2以前程序使用Thread类定义的suspend()、resume()和stop()方法。但它们有时会造成严重的系统故障。Java的现代版本里,线程必须被设计为run()方法周期性地进行检查,以确定时候应当挂起、恢复或停止线程自身的执行。通常,这是通过建立用来标识线程执行状态的变量完成的。

获取线程的状态:getState()。返回的是Thread.State类型的值。State是由Threat类定义的枚举类型。但在调用此方法后,线程的状态可能会发生变化。此方法的主要用于调试或显示线程的运行时特征。

有效利用Java多线程特性的关键是并发地而不是顺序地思考问题。
当创建的特征老多时,请记住,线程上下文切换需要一定的开销。
对于多核系统,考虑Java的Fork/Join框架。
posted @ 2016-06-21 15:53  StevenLuke  阅读(109)  评论(0编辑  收藏  举报