Java学习笔记(三) — 线程


Lesson 5

1.进程与线程的概念

  • 进程

    在多任务系统中,每个独立执行的程序称为进程;进程就是“正在进行的程序”。
    (可以说,进程process是一个程序的动态表现,或动态模型;程序一般为二进制文件,存储在存储介质中,未调入内存前是“不动的、静态的”,而进程则是被调入内存参与运行的程序,可视为“活动的程序,即active application”)

  • 线程

    一个进程中又可以包含一个或多个线程,一个线程就是一个程序内部的一条执行线索;
    如一个程序中实现多段代码同时交替运行,就需产生多个线程,并指定每个线程上所要运行的程序代码段;
    (线程是对进程中代码的进一步细粒度划分,可以说,线程就是进程的”活动的”代码段)

2.线程的创建

Java中Java.lang.thread代表一个线程类,一个thread对象代表且只代表一个线程。

3.线程的执行

为类库java.lang.thread派生一个子类,重载其中的 run() 方法;新生一个子类对象,调用对象中的 start() 方法。

3.1 框架封装思想分析

计算机完成任何一个任务,都有一个完整的执行线索,完全掌握这个执行线索,当然可以对任务执行有良好控制。

但是,实际应用中,执行线索中很多例行工作都是从重复性劳动,为减轻programmer的负担,可将整个任务的执行线索封装起来,由框架自动执行,为用户留下一个公开的启动接口来启动任务(有时启动任务接口都被封装)。

因为不同任务除了共有的重复性动作外,还有特色行为,为了对程序进行特色控制,在整个过程中“挖”出若干切入点,开发者只要改写切入点处的代码,就可以自然的将特色行为融入整个任务执行线索中,此种方法大大降低了开发人员的工作量,使得开发人员只需关注“切入点”即可。

在面向对象的框架实现中,整个执行线索和切入点被封装在多个类中,开发者看不到整个执行线索(被封装,编译时自动链接),只看到一个个“零散”的类,对这些“零散”的类中的方法进行修改或派生重载,即完成整个执行任务的特色行为添加。MFC即是这种特点。Java多线程这里也体现了这一点。

pic

3.2 线程的执行状态

Java中的线程分为 前台线程 和 后台线程。线程执行状态决定了进程的消亡。

对Java程序而言,只要有一个前台线程在运行,这个进程就不会结束;如果一个进程中只有后台线程在运行,这个进程就会结束。(这意味着后台线程也会被迫结束?)

Thread类中的setDaemon(true/false)用于改变线程的前/后台状态。

3.3 多线程的执行

多线程的本质是对CPU运算能力的争夺。
多线程编程本质是要并发执行任务的结果。

任何一个线程获得CPU执行时间片时,对其内部的代码都是按顺序执行的。也就是说,

statement A;
statement B;

如果statement A与statement B在同一个线程中,且statement A位于statement B前面,则statement A不执行完毕,CPU是无法执行statement B的。

若要想让statement B的执行不受制于statement A,则应将statement B放置于不同于statement A的另一个线程中。

3.4 线程间的同步

共享资源的争夺是多线程中的核心问题,本质原因是CPU切换的不可预测性(不可控性)
Java多线程并发造成的共享变量差错本质是由于语言的语句粒度大的原因。C/C++也是如此。
线程本身无法控制CPU的切换,CPU的切换本质上是由OS调度的。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注