第一章 走进java线程中的世界--《java多线程编程实战指南-核心篇》

1.1 进程、线程和任务

进程是程序向操作系统申请资源(如内存空间和文件句柄)的基本单位。线程是进程中可独立执行的最小单位。

一个进程可以包含多个线程。同一个进程中的所有线程共享该进程中的资源。

线程所要完成的计算就被称为任务,特定的线程总是在执行特定的任务。

1.2 多线程编程简述

函数式编程中的函数是最基本抽象单元,面向对象编程中的类是最基本抽象单位,多线程编程中以线程为基本抽象单位;实际上java平台中的一个线程就是一个对象。

增加线程可能会增加单位时间内完成的任务量,即提高程序的计算效率;但它也可能降低程序的计算效率。

1.3 java线程API简介

在java平台中创建一个线程就是创建一个Thread类或其子类的实例,其run方法相当于线程的任务处理逻辑的入口方法,它由java虚拟机在运行相应的线程时直接调用,而不是由应用代码进行调用。

运行一个线程实际上就是让java虚拟机执行该线程的run方法,从而使线程的任务处理逻辑代码得以执行。Thread类的start方法的作用是启动相应的线程。启动一个线程的实质是请求java虚拟机运行相应的线程,而这个线程具体何时能够运行是由线程调度器决定的。因此,start方法调用结束并不意味着相应线程已经开始运行,这个线程可能稍后才会被运行,甚至可能永远不会被执行。

运行结束的线程所占用的资源(如内存空间)会如同其他java对象一样被java虚拟机垃圾回收。线程是一次性用品,不能重复调用start方法使其重新运行,start方法只能调用一次。

java中一个线程就是一个对象,对象的创建离不开内存空间的分配。创建一个线程与创建其他类型的java对象所不同的是,java虚拟机会为每一个线程分配调用栈所需的内存空间。调用栈用于跟踪java代码间的调用关系以及java代码对本地代码的调用。另外,java平台中的每个线程可能还有一个内核线程与之对应。因此创建线程对象比创建其他类型的对象成本要高一些。

关于创建Thread类实例还是创建Runnable接口:1.一个是基于继承的技术,一个是基于组合的技术;2.创建Runnable实例意味着多个线程可以共享一个Runnale实例;3.创建成本上,java中的线程实例是一个特殊的Runnable实例,因为在创建它的时候java虚拟机会为其分配调用栈空间、内核线程等资源。因此,创建一个线程实例比创建一个普通的Runnable实例来说,成本相对高昂一些。

线程包含编号、名称、线程类别和优先级四个属性。关于线程类别:分为守护线程和用户线程,用户线程会组织java虚拟机的正常停止,即一个java虚拟机只有在其所有用户线程都运行结束的情况下才能正常停止,而守护线程则不会影响java虚拟机的正常停止,即应用程序中有守护线程在运行也不影响java虚拟机的正常停止;关于线程优先级:java线程的优先级使用不当或者滥用则可能导致某些线程永远无法得到运行,即产生线程饥饿。

Thread类的常用方法:

1.4 线程的层次关系

线程A所执行的代码创建了线程B,那么线程B是线程A的子线程,线程A是线程B的父线程。

1.5 线程的生命周期状态

NEW:一个已创建而未启动的线程处于该状态。由于一个线程实例只能够被启动一次,因此一个线程只可能有一次处于该状态。

RUNNABLE:该状态可被看成一个复合状态。它包括两个子状态:READY和RUNNING。前者标识处于该状态的线程可以被线程调度器进行调度而使之处于RUNNING状态。后者表示处于该状态的线程正在运行,即相应线程对象的run方法所对应的指令正在由处理器执行。执行Thread.yield()的线程,其状态可能会由RUNNING转换为READY。处于READY子状态的线程也被称为活跃线程。

BLOCKED:一个线程发起一个阻塞式I/O操作后,或者申请一个由其他线程持有的独占资源时,相应的线程会处于该状态。处于BLOCKED状态的线程并不会占用处理器资源。当阻塞式I/O操作完成后,或者线程获得了其申请的资源,该线程的状态有可能转换为RUNNABLE。

WAITING:一个线程执行了某些特定方法之后就会处于这种等待其他线程执行另外一些特定操作的状态。能够使其执行线程变更为WAITING状态的方法包括:Object.wait()、Thread.join()和LockSupport.park(Object)。能够使相应线程从WAITING变更为RUNNABLE的响应方法包括:Object.notify()/notifyAll()和LockSupport.unpark(Object)。

TIMED_WAITING:该状态和WATING类似,差别在于处于该状态的线程并非无限制地等待其他线程执行特定操作,而是处于带有时间限制的等待状态。当其他线程没有在指定时间内执行该线程所期望的特定操作时,该线程的状态自动转换为RUNNABLE。

TERMINATED:已经执行结束的线程处于该状态。由于一个线程实例只能被启动一次,因此一个线程也只可能有一次处于该状态。Thread.run()正常返回或者由于抛出异常而提前终止都会导致响应线程处于该状态。

一个线程在其整个生命周期中,只可能有一次处于NEW状态和TERMINATED状态。

1.6 多线程编程的优势和风险

优势:1.提高系统吞吐率;2.提高响应性;3.充分利用多核处理器资源;4.最小化系统资源的使用;5.简化程序结构,线程可以简化复杂应用程序的结构;

风险:1.线程安全问题;2.线程活性问题(某些线程一直处于等待其他线程释放锁状态,即产生死锁;一个线程在尝试某个操作但就是无法紧张,即产生活锁);3.上下文切换;4.可靠性;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章