第十章线程、文件与串行化 本章将讨论有关线程及输入/输出的一些高 级话题。首先,讲述了线程和并发编程的基 本概念、模型和应用;然后阐述怎样从文件 中读取数据和将数据写入文件,其中包括 ava中最常见的输入/输出流;最后介绍了 对象串行化以及如何用对象流实现串行化
Java程序设计大学教程 第十章 线程、文件与串行化 本章将讨论有关线程及输入/输出的一些高 级话题。首先,讲述了线程和并发编程的基 本概念、模型和应用;然后阐述怎样从文件 中读取数据和将数据写入文件,其中包括 Java中最常见的输入/输出流;最后介绍了 对象串行化以及如何用对象流实现串行化
10.1多线程程序设计 ■多线程程序能够使程序的不同部分同时运行 ■现代操作系统和许多科学应用都是多线程程序。 使用多线程编程可以解决后台任务、并发操作 管理用户界面等编程难题,多线程程序设计因此 也越来越重要
Java程序设计大学教程 10.1 多线程程序设计 ◼ 多线程程序能够使程序的不同部分同时运行。 ◼ 现代操作系统和许多科学应用都是多线程程序。 ◼ 使用多线程编程可以解决后台任务、并发操作、 管理用户界面等编程难题,多线程程序设计因此 也越来越重要
10.1.1多任务、进程和线程 在多任务操作系统中,通常一个运行的程序实例称为一个 进程。进程也就是调入内存准备执行的程序。每个进程都 在自己分配的空间内独立运行,进程与进程之间互不干扰 ■线程是程序中的一个可执行语句序列,是一个单独的运行 过程。通常,每个进程至少有一个线程(即主线程)在执 行自己的地址空间中的代码。线程是进程内部执行的路径, 是操作系统分配CPU时间的基本实体。 ■每个进程都可以包含多个线程,它们可以同时独立地执行 进程的地址空间中的代码。进程的所有线程共享进程的地 址空间。在基于线程的多任务处理环境中,线程是最小的 执行单位
Java程序设计大学教程 10.1.1 多任务、进程和线程 ◼ 在多任务操作系统中,通常一个运行的程序实例称为一个 进程。进程也就是调入内存准备执行的程序。每个进程都 在自己分配的空间内独立运行,进程与进程之间互不干扰。 ◼ 线程是程序中的一个可执行语句序列,是一个单独的运行 过程。通常,每个进程至少有一个线程(即主线程)在执 行自己的地址空间中的代码。线程是进程内部执行的路径, 是操作系统分配CPU时间的基本实体。 ◼ 每个进程都可以包含多个线程,它们可以同时独立地执行 进程的地址空间中的代码。进程的所有线程共享进程的地 址空间。在基于线程的多任务处理环境中,线程是最小的 执行单位
10.1.1多任务、进程和线程 应用程序为了实现多任务并行处理,可以采用创 建多个进程和在单一进程中创建多线程两种方法, 但后者比前者更有效,这是因为: ■线程是轻量级的任务,线程的代码已经映射到了 进程的地址空间,而新进程的代码还需要载入内 存,所以系统创建和执行线程要比创建和执行进 程快得多;而进程是重量级的任务,需要更多的 管理开销和系统资源。 ■进程的所有线程共享进程的地址空间,并能够访 问进程的全局变量,因而线程之间的通信会更便 捷,线程间的转换也是低成本的
Java程序设计大学教程 10.1.1 多任务、进程和线程 应用程序为了实现多任务并行处理,可以采用创 建多个进程和在单一进程中创建多线程两种方法, 但后者比前者更有效,这是因为: ◼ 线程是轻量级的任务,线程的代码已经映射到了 进程的地址空间,而新进程的代码还需要载入内 存,所以系统创建和执行线程要比创建和执行进 程快得多;而进程是重量级的任务,需要更多的 管理开销和系统资源。 ◼ 进程的所有线程共享进程的地址空间,并能够访 问进程的全局变量,因而线程之间的通信会更便 捷,线程间的转换也是低成本的
10.1.2]ava线程模型 当]ava程序运行时,立即启动一个主线程( main thread), 它由我们熟悉的main方法开始执行。主线程可以起的作用是: 口启动程序进程 口负责创建其他子线程 口负责完成整个进程最后的各种清理和关闭任务 尽管主线程在程序启动时自动创建,但仍然可以通过 Thread. currentthread方法将其作为线程对象调用。要创建 个线程,可以通过实例化一个线程对象来实现。Java给出了两 种方式: 口继承 Thread类 口实现 Runnable接口
Java程序设计大学教程 10.1.2 Java线程模型 当Java程序运行时,立即启动一个主线程(main thread), 它由我们熟悉的main方法开始执行。主线程可以起的作用是: 启动程序进程 负责创建其他子线程 负责完成整个进程最后的各种清理和关闭任务 尽管主线程在程序启动时自动创建,但仍然可以通过 Thread.currentThread方法将其作为线程对象调用。要创建一 个线程,可以通过实例化一个线程对象来实现。Java给出了两 种方式: 继承Thread类 实现Runnable接口
10.1.2]ava线程模型 C: \WINDOWSIsystem32icmdexe -口x 新线程1启动!新线程2启动!新线程3启动!新线程4启动!主线程启动! 12341234123412341234123412341234441444444444444444321 >321 321->321 321 321 321-->321 321 1234123412341234123412341234123412344 44444444444444444321 321 321 321 321 321 321-321-4343434343434343433333333333333333334-)124- 124 124 124 124 124 124 ->124 122222222 222222221 431 431-)431-)431--)431--)431->4 431 433333333333333333334 124 124->124->124 >124 124 124-->124 122222222222222222221 >431 431->431 431->431 4333 线程3结束!44线程4结束 〉1212121 2121212121222线程2结束 111111111111111111 主线程结束11线程1结束|请按任意键继续
Java程序设计大学教程 10.1.2 Java线程模型 ◼ 当Java程序运行时,它由main方法启动一个主线程。 而用run方法启动一个子线程。对于新创建的线程。调用 了该线程的start方法之后,就会自动调用线程对象的 run方法。 ◼ 线程是异步的,这就意味着执行的顺序和一系列线程的 时序是零散而不可预测的,至少从编程者的角度看是这 样的。 ◼ 异步线程原则:除非它们是明确地有优先级的或者是严 格同步的,否则线程是以完全异步的方式运行的。负责 完成整个进程最后的各种清理和关闭任务。 ◼ 多线程程序MultiThreadDemo1运行演示
10.1.2]ava线程模型 每个线程都有一个生命周期,它是由若干个不同的 状态组成的。这些状态包括: ■就绪线程做好了运行准备并在等待CPU ■运行线程在CPU上执行 ■等待线程在等待发生某个事件 休眠线程已被告知要休眠一段时间 start( 阻塞线程在等待I/O结束结東 一就绪 notifyAll ( 死亡线程被终止 分派 超时 阻塞 等待 I/o请求二 stopt ()
Java程序设计大学教程 10.1.2 Java线程模型 每个线程都有一个生命周期,它是由若干个不同的 状态组成的。这些状态包括: ◼ 就绪 线程做好了运行准备并在等待CPU ◼ 运行 线程在CPU上执行 ◼ 等待 线程在等待发生某个事件 ◼ 休眠 线程已被告知要休眠一段时间 ◼ 阻塞 线程在等待I/O结束 ◼ 死亡 线程被终止 就绪 运行 死亡 阻塞 休眠 等待 start() notify() I/O结束 超时 I/O请求 stopt() wait() sleep() notifyAll() 分派
10.1.2]ava线程模型 Ca C: \ INDOWSIsystem32\cmd.exe 新线程1启动!新线程2启动!新线程3启动!新线程4启动!444 1444444444444444444444444444444444444444444441444444444444 444 4444结束 线程启动! 2323232323 323233333333333333333332-)2-)2-)2-2 232323232323232323 3333333333333332-〉2-)2-〉2-)2-〉2->2->2 232323232323232323333333 333333333332)2->2->2->2-)2->2->2->2 232323232323232323333333333333 3333332 2-- >主线程结束!22023 333333333333333333322222222222222223333333333 333333300033333 结束 2线程2结束1111 111111111 1111111111111111111111111111111111111111111111111111111111111111111111111111111 11111!请按任意键继续
Java程序设计大学教程 10.1.2 Java线程模型 ◼ 线程休眠是线程的一种最重要的状态,它可以主动让出 CPU时间,消除资源竞争导致的阻塞。Thread.sleep方 法可以按照毫秒级的时间使线程保持休眠状态,从而允 许其他等待着的线程运行。 ◼ 理论上,优先级高的线程比优先级低的线程获得更多的CPU时 间。但实际上,线程获得的CPU时间通常是由包括优先级在内 的多种因素决定的。 ◼ 要设置线程优先级,可用Thread.setPriority方法。它将一个 线程的优先级设置成一个整数值,该整数值在1和10之间。 ◼ 协调两个线程之间的行为的一种方式是设定其中一个线程有更 高的优先级。但一个永远都不放弃占有CPU的高优先级线程会 导致低优先级线程过度等待。 ◼ 带优先级控制的多线程程序运行演示 ( MultiThreadDemo3)
10.1.3设计多线程的应用程序 JPanel Bubble canvas Bubble -bubbles: ArrayList -canvas Component -X Size: int +add void -ySize: int +paint component void -xint Thread Bubble Thread dx. int -dy int -b: Bubble bubble Color Color JFrame MainFrame +Bubble thread +Bubble +run: void +draw void canvas: Bubble Canvas enlarge void +WIDTH: int +HEIGHT: int Bubble ThreadDemo color: color +Main Fra +add Button void +add Bubble void +main yoid
Java程序设计大学教程 10.1.3 设计多线程的应用程序 ◼ 在Java程序中,并发编程是通过多线程实 现的。利用多线程编程的好处是能够让一 个程序同时执行多个任务,这在设计动画 时尤其重要。因为动画中通常有多个动画 对象需要同时绘制,而不是等一个对象绘 制完成后在绘制另一个对象。 ◼ 多线程演示程序BubbleThreadDemo的 设计
10.2流和文件 ■流指的是一种数据流。如果数据流写入程序中,那么该数据流 称为输人流;相反,从程序中输岀的数据流称为输岀流。如果 输入数据流来自键盘,则程序从键盘读取数据;如果输入数据 流来自文件,则程序从文件读取数据。类似地,输出数据流则 输出至文件或屏幕。 ■输入是指运行的程序从某个外部数据源读取信息或数据。当程 序有输人数据时,它们或者来自键盘,或者来自GUI界面中的 组件(如 JTextField)。输出是指运行的程序将信息或数据写 到某个外部目标中。当程序产生了输出,会被送到屏幕(控制 台程序)、GUI组件或文件中 ■文件是保存在磁盘上或者其他持久性存储媒介上的数据集合。 文件的存在并不依赖于运行的程序。文件通过流实现输入和输 出操作
Java程序设计大学教程 10.2 流和文件 ◼ 流指的是一种数据流。如果数据流写入程序中,那么该数据流 称为输人流;相反,从程序中输出的数据流称为输出流。如果 输入数据流来自键盘,则程序从键盘读取数据;如果输入数据 流来自文件,则程序从文件读取数据。类似地,输出数据流则 输出至文件或屏幕。 ◼ 输入是指运行的程序从某个外部数据源读取信息或数据。当程 序有输人数据时,它们或者来自键盘,或者来自GUI界面中的 组件(如JTextField)。输出是指运行的程序将信息或数据写 到某个外部目标中。当程序产生了输出,会被送到屏幕(控制 台程序)、GUI组件或文件中。 ◼ 文件是保存在磁盘上或者其他持久性存储媒介上的数据集合。 文件的存在并不依赖于运行的程序。文件通过流实现输入和输 出操作