java(朱福喜)_第八章线程08例子源程序

合集下载

java第八章

java第八章

创建线程的方式
(2) 实现 实现Runnable接口来创建并启动多条线程的步骤如下: 接口来创建并启动多条线程的步骤如下: 接口来创建并启动多条线程的步骤如下 ① 定义Runnable接口的实现类,并重写该接口的run方法,该run 方法的方法体同样是该线程的线程执行体。 ② 创建Runnable实现类的实例,并以此为实例作为Thread的参数 来创建Thread对象,该Thread对象才是真正的线程对象。 class SencondThread implements Runnable{} SencondThread st = new SencondThread(); new Thread(st); 创建Thread对象时为该 对象时为该Thread对象指定一个名字 创建 对象时为该 对象指定一个名字 new Thread(st,”新线程 新线程1”); 新线程 例:CreateThread2.java
例:TestStop.java
死亡状态( 死亡状态( isAlive )
isAlive()方法: Tests been
if this thread is alive. A thread is alive if it has started and has not yet died.
如果线程已被启动并且未被终止,那么isAlive(
线程同步之生产者消费者问题
为了解决所出现的问题,在Java语言中可以用wait () 和 notify()/notifyAll()方法(在ng.Object类中定义)来协 调线程间的运行进度(读取)关系。 wait()方法的作用是让当前线程释放其所持有的“对象互 斥锁”,进入wait队列(等待队列);而notify()/notifyAll() 方法的作用是唤醒一个或所有正在等待队列中等待的线程 ,并将它(们)移入等待同一个“对象互斥锁”的队列。 需要指出的是: 需要指出的是: notify()/notifyAll()方法和wait ()方法都 只能在被声明为synchronized的方法或代码段中调用。 ProducerConsumer.java

java课件——第八章

java课件——第八章

线程的生命周期
线程在它的一个完整的生命周期中通常要经历4 线程在它的一个完整的生命周期中通常要经历4 种状态, 种状态, new 此时的线对象仅仅是普通的对象 Runnable(可运行状态) Runnable(可运行状态) 系统为线程分配了它运行所需要的资源, 系统为线程分配了它运行所需要的资源,它 或者在就绪队列里等待执行,或者正在执行. 或者在就绪队列里等待执行,或者正在执行.
第八章
线程
《主要内容》 主要内容》 线程概念 线程的生命周期 线程的创建 线程的常用方法
程序, 程序,进程与线程 程序是一段静态的代码,它表现为磁盘上的一个文件. 程序是一段静态的代码,它表现为磁盘上的一个文件. 是一段静态的代码 进程是程序的一次动态执行过程, 进程是程序的一次动态执行过程,进程包括代码以及系 是程序的一次动态执行过程 统为了执行它而分配给它的一系列资源. 统为了执行它而分配给它的一系列资源. 线程是比进程更小的执行单位.一个进程在其执行过程 线程是比进程更小的执行单位. 是比进程更小的执行单位 可以产生多个线程,每个线程也有它自身的产生, 中,可以产生多个线程,每个线程也有它自身的产生, 存在和消亡的过程,也是一个动态的概念. 存在和消亡的过程,也是一个动态的概念.
中断. 中断. 有4种原因的中断: 种原因的中断: ⒈ JVM将CPU资源从当前线程切换给其他线程,使本 JVM将CPU资源从当前线程切换给其他线程, 资源从当前线程切换给其他线程 线程让出CPU的使用权处于中断状态. CPU的使用权处于中断状态 线程让出CPU的使用权处于中断状态. 线程执行了Thread.sleep(int millsecond)方法 方法, ⒉ 线程执行了Thread.sleep(int millsecond)方法, 使当前线程进入休眠状态. 使当前线程进入休眠状态. 线程一旦执行了sleep(int millsecond)方法 方法, 线程一旦执行了sleep(int millsecond)方法,就立 刻让出CPU的使用权,使当前线程处于中断状态. CPU的使用权 刻让出CPU的使用权,使当前线程处于中断状态.经 过参数millsecond指定的豪秒数之后, millsecond指定的豪秒数之后 过参数millsecond指定的豪秒数之后,该线程就重新 进到线程队列中排队等待CPU资源, CPU资源 进到线程队列中排队等待CPU资源,以便从中断处继 续运行. 续运行.

java_8多线程_课件2016-xhu

java_8多线程_课件2016-xhu

}
22
23
8.2多线程实现方法
2.实现Runnable接口
什么是Runnable接口?
a) Runnable是ng包中的一个接口。
b) 定义了创建和执行线程的功能。
c) 定义了run()方法,完成具体任务的地方。
24
实现Runnable接口
实现Runnable接口的主要步骤: ① 定义一个类实现Runnable接口, class FirstThread implements Runnable ② 并且在该类中实现run()方法。
public void run()
② 生成这个类的对象。 FirstThread first = new FirstThread();

用Thread(Runnable target)构造函数生成Thread对象,然后调用start()方 法启动线程。
Thread thread1 = new Thread(first);
21
class TestSailThread{ public static void main(String []args){ SailThread t1=new SailThread(1); SailThread t2=new SailThread(2); SailThread t3=new SailThread(3); SailThread t4=new SailThread(4); t1.start(); t2.start(); t3.start(); t4.start(); }
18
Thread子类线程小结(加深理解)
需要深入理解线程的run()以及start()方法:
• start()方法将调用run()方法执行线程。 • run()方法就是新线程完成具体工作的地方。 注意通过对比加深了解: 程序的入口, main() 方法。 线程的入口, run() 方法。 Applet的入口,init()方法。

java语言程序设计基础篇(第八版)课件PPT第八章

java语言程序设计基础篇(第八版)课件PPT第八章
Liang, Introduction to Java Programming, Eighth Edition, (c) 2011 Pearson Education, Inc. All rights reserved. 0132130807
3
OO Programming Concepts
Object-oriented programming (OOP) involves programming using objects. An object represents an entity in the real world that can be distinctly identified. For example, a student, a desk, a circle, a button, and even a loan can all be viewed as objects. An object has a unique identity, state, and behaviors. The state of an object consists of a set of data fields (also known as properties) with their current values. The behavior of an object is defined by a set of methods.
5
Classes
Classes are constructs that define objects of the same type. A Java class uses variables to define data fields and methods to define behaviors. Additionally, a class provides a special type of methods, known as constructors, which are invoked to construct objects from the class.

Java程序设计教程 第八章

Java程序设计教程 第八章

数据成员
Protected String buffer Protected int count Protected int pos
说明
用来储存将要读取的字符 缓冲内的有效数目 指向将要读取字符的指针
8.2.3 管道流
“管道”的概念:即它把一个程序的输出与另一 个程序的输入连接起来,传送的同样是字符流。 表8-4是PipedInputStream的数据成员:
图8-1 读取数据操作
图8-2 写入数据操作
8.1 输入输出概述
使用一个流对象,就可以方便地进行读取 或写入操作。在前面的章节里,就已经接 触过System.out,它就是一个PrintStream 实例。已知它有方法println(String),一条语 句System.out.println("Hello World!")就会在 控制台窗口显示Hello World!。另外, System.in是一个InputStream实例。 所有的输入输出类都直接或间接地从两个基 类派生而来,这两个基类分别是 InputStream和OutputStream两个抽象类。
8.2.6 文件流FileStream
3. 文件输出流:FileOutputStream类
一个文件输出流的工作是把内容输出到一个File或者一个 FileDescriptor。FileOutputStream类的构造函数如表8-10
函数名 FileOutputStream(File file) 说明 将内容写入file所代表的文件对象
8.2.1 字节流
ByteArrayOutputStream类的构造方法有两种: 一种是无参数构造方法,另一种原型是 ByteArrayOutputStream(int size),size指定了数 组大小。该类拥有的数据成员见表8-2。 数据成员

java第八章答案

java第八章答案

1.进程和线程有何区别,Java是如何实现多线程的。

答:区别:一个程序至少有一个进程,一个进程至少有一个线程;线程的划分尺度小于进程;进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。

Java程序一般是继承Thread 类或者实现 Runnable接口,从而实现多线程。

2.简述线程的生命周期,重点注意线程阻塞的几种情况,以及如何重回就绪状态。

答:线程的声明周期:新建-就绪-(阻塞)-运行--死亡线程阻塞的情况:休眠、进入对象wait池等待、进入对象lock池等待;休眠时间到回到就绪状态;在wait池中获得notify()进入lock池,然后获得锁棋标进入就绪状态。

3.随便选择两个城市作为预选旅游目标。

实现两个独立的线程分别显示10次城市名,每次显示后休眠一段随机时间(1000毫秒以内),哪个先显示完毕,就决定去哪个城市。

分别用Runnable接口和Thread类实现。

(注:两个类,相同一个测试类)//Runnable接口实现的线程runable类public class runnable implements Runnable {private String city;public runnable() {}public runnable(String city) {this.city = city;}public void run() {for (int i = 0; i < 10; i++) {System.out.println(city);try {//休眠1000毫秒。

Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}}// Thread类实现的线程thread类public class runnable extends Thread {private String city;public runnable() {}public runnable(String city) {this.city = city;}public void run() {for (int i = 0; i < 10; i++) {System.out.println(city);try {//休眠1000毫秒。

Java程序设计实用教程(第2版)第8章_内部类与异常类

Java程序设计实用教程(第2版)第8章_内部类与异常类
new Bank () { 匿名类的类体 };
匿名类的常用的方式是向方法的参数传值。
void f(A a){ 2017/8/16 }
4
例8-2
InputAlphabet.java , InputEnglish.java ShowBoard.java, Example8_2.java
2017/8/16
2017/8/16
10
例子5
DangerException.java
CargoBoat.java
Example8_5.java 通过例子5熟悉带finally子语句的try~catch语句。例子5 中模拟向货船上装载集装箱,如果货船超重,那么货 船认为这是一个异常,将拒绝装载集装箱,但无论是 否发生异常,货船都需要正点启航。运行效果如图8.5。
try {
包含可能发生异常的语句
} catch(ExceptionSubClass1 … … } catch(ExceptionSubClass2 … … }
e) {
e) {
2017/8/16
9
例8-4
Example8_4.java
例8-4给出了try~catch语句的用法, 程序运行效果如图8.4所示。
public String getMessage(); public void printStackTrace(); public String toString();
2017/8/16
8
§8.3.1 try~catch语句 Java 使用 try~catch 语句来处理异常,将可能出现 的异常操作放在 try~catch语句的 try 部分,将发生异常 后的处理放在catch部分。 try~catch语句的格式如下:

Java程序设计实例教程-第8章

Java程序设计实例教程-第8章

Thread(Runnable t,String name)
Thread(String name)
启动线程 start()方法可以启动线程,开始执行run()中代码。即:run() 内代码,不是调用执行,而是启动后,由虚拟机自动执行 的。
版权所有:计算机系
class MyThread extends Thread { public void run( ){ for(int i=1;i<=30;i++){ System.out.println(“线程”+getName()+“正在打印"+i); } } public static void main(String[] args) { System.out.println(“main开始执行…………”); MyThread mt = new MyThread(); //MyThread mt2 = new MyThread(); mt.start( ); //mt2.start( ); for(int i =1;i<=30;i++){ System.out.println(“线程main正在打印"+i); } } }
在同一时间点执行各项进程 • 编译程序
程序 (进程)
• 发送/接收邮件 • 打印文件 • 其他
版权所有:计算机系
A Thread
A Program
Two Thread
B Program
版权所有:计算机系
public class mainClass { public static void main(String agrs[]){ m1(); } public static void m1(){ m2(); m3(); } public static void m2(){ } public static void m3(){ } }

《Java程序设计案例教程》第08章

《Java程序设计案例教程》第08章

public static void main(String[] args) {

int a = 0;
int b = 8 / a;
// a 的值为0,被0除是无法计算的
}
}
❖ 因为除数为0,产生的异常名为算术异常ArithmeticException
❖ 其它常见的异常有
▪ 空指针异常NullPointerException
} catch (ArithmeticException e) { System.out.println("出现算术异常, 异常信息是: " + e.getMessage());
}
Java程序设计案例教程
幻灯片 11,共24页
11
8.1.2 捕获异常
❖ 把可能产生异常情况的语句放在try语句块中,这个语句块用来启动Java的异 常处理机制
System.out.println("其它异常." + e.getMessage());
return;
} finally {
// 不论出现异常与否,这部分总会执行
System.out.println("善后处理.");
}
System.out.println("程序正常结束.");
}
}
Java程序设计案例教程
} } public class ExceptionDemo7 {
public static void main(String[] args) { int i = -1; try { i = Example.readScore(); System.out.println(i); } catch (ScoreException e) { System.out.println(e.getMessage()); }

《Java程序设计(人邮,朱喜福)》实验指导书

《Java程序设计(人邮,朱喜福)》实验指导书

《JAVA程序设计》实验指导书实验指导书按章节展开,每章包含以下内容:1.概念复习和巩固题(必做)。

每次课后和上机前,请完成本章的概念复习和巩固题。

2.每章的上机实验(必做)。

每次上机实验时间为2课时。

必须在规定上机时间内,独立完成所有上机实验题的程序源代码的设计和编写,调试通过后,通过运行程序检验结果的正确性,并经实验教师检查并记录成绩。

上机实验当时未能完成的,必须在课外完成,并在下一次上机实验时请实验教师补查并登记。

每次上机实验作业均需计算机打印输出,以备在课堂上或学期末检查和复习。

3.每章的拓展上机实验(选做)。

对学有余力的学生,完成每次上机实验必须的任务后,根据个人兴趣完成该部分上机实验题。

该部分练习有些是要求调试程序使之能正确运行;有些是根据程序中的注释完成程序的编写,使之能编译通过并能正确运行。

完成这些任务,通常需要查阅JavaAPI帮助文档。

程序中的注释都是英文,这是为了今后进一步学习的方便,熟悉与Java编程相关的英文描述将是非常有益的。

第1章Java语言基础一. 概念复习和巩固(请在课后和上机前完成下面的练习)1.下面说法正确的是( C )。

A)Java 程序的源文件名称与主类(公共类)的名称相同,后缀可以是java或txt等。

B)JDK的编译命令是java。

C)一个java源程序编译后可能产生几个字节码文件。

D)在命令行运行编译好的字节码文件,只需在命令行直接键入程序名即可运行该程序。

2.下面的说法正确的是(ABCD)。

A) Java 语言是面向对象的、解释执行的网络编程语言。

B) Java 语言具有可移植性,是与平台无关的编程语言。

C) Java 语言可对内存垃圾自动收集。

D) Java 语言编写的程序虽然是“一次编译,到处运行”,但必须要java的运行环境。

3.下面main()方法的定义哪些是正确的(ACD)?A)public static void main(String args[]) {}B)public static void main(String[]) {}C)public static void main(String[] args) {}D)public static void main(String [] x) {}4.用于定义数据简单类型的一组关键字是(B)。

电子教案-面向对象与Java程序设计 (第3版)-微课视频版-朱福喜-清华大学出版社

电子教案-面向对象与Java程序设计 (第3版)-微课视频版-朱福喜-清华大学出版社

面向对象与Java程序设计(第3版)课程教案任课教师:朱福喜开课对象:软件工程学时/学分:64/4 课堂教学/课内实验: 42/22使用教材:朱福喜,《面向对象与Java程序设计》第2版,清华大学出版社,2015.7主要参考书:1. 叶核亚,《Java程序设计实用教程(第3版)》,电子工业出版社,20102. 耿祥义、张跃平,《Java大学实用教程(第2版)》,电子工业出版社,2008年3. 孙卫琴,《Java 面向对象编程》,电子工业出版社,20064. 张白一,《面向对象程序设计—Java》,西安电子科技大学出版社, 20085. 陈国君,《Java程序设计基础》(第4版),清华大学出版社,2014.86. (美)刘易斯、洛夫特斯著,罗省贤,李军译,《Java程序设计教程》(第六版),电子工业出版社,2009.17. Cay S. Horstmann / Gary Cornell ,《Core Java》, Prentice Hall PTR,20048. 埃克尔,陈昊鹏译,《Java 编程思想》,机械工业出版社,2007课程总体目标本课程是软件工程专业开设的学科基础课。

本课程的教学任务是通过Java 程序设计的课堂讲授、课内实验,课外自主试验等教学环节,培养学生程序设计使用Java语言进行程序设计的基本能力,并且养成学生良好的编程习惯和规范的编程风格。

使学生掌握较扎实的 Java 语言基础,理解面向对象程序设计的思想,为Java后续课程的学习打下坚实的基础。

课程的主要内容如下:1、绪论2、Java程序设计基础3、Java面向对象程序设计4、数组、字符串、向量和哈希表5、泛型、枚举与for语句的简化写法6、Java异常处理与递归7、文件与数据流8、Java图形用户界面程序设计9、多线程程序设计10、网络程序设计第1章绪论一、教学目的和要求了解Java语言的发展历史,Java语言的特点,学会安装配置Java开发环境,能够编译和运行Java程序。

Java语言程序设计案例教程-第8章

Java语言程序设计案例教程-第8章

2021/8/6
4
8.1 Java图形用户界面概述
容器的主要作用和特点有: (1)容器有一定的范围。一般容器都是矩形的,容器范围边界可以用边框框 出来,有些则没有可见的标记。 (2)容器有一定的位置。这个位置可以是屏幕四角的绝对位置,也可以是相 对于其他容器边框的相对位置。 (3)容器通常都有一个背景,这个背景覆盖全部容器,可以透明,也可以指 定一幅特殊的图案,使界面生动化和个性化。 (4)容器中可以包含其他的许多界面成份和元素。当容器被打开显示时,它 上面的成份和元素也同时显示出来;当容器被关闭和隐藏时,它所包含的成 份和元素也一起被隐藏。 (5)容器可以按一定的规则来安排它所包含的元素,如这些元素的相对位置 关系、它们的前后排列关系等。 (6)容器可能被包含在其他容器之中。
2021/8/6
5
8.1 Java图形用户界面概述
2.控制组件
与容器不同,控制组件是图形用户界面的最小单位之一,它里面不再包含其 他的元素。控制组件的作用是完成与用户的一次交互,包括接受用户的一个 命令,接受用户的一个文本输入,向用户显示一段文本或一个图形等。从某 种程度上来说,控制组件是图形用户界面标准化的结果。 3.用户自定义成分 除了标准的图形界面元素,编程人员还可以根据用户需要设计一些用户自定 义的图形界面成份,例如绘制一些几何图形,使用标志图案等。用户自定义 成份由于不能像标准界面元素一样被系统识别和承认,所以通常只能起到装 饰、美化等作用,而不能响应用户的动作,不具有交互功能。
2021/8/6
10
8.2 标准组件
8.2.1 容器类组件
容器分为两种:顶层容器和非顶层容器两大类。顶层容器是可以独立的窗口, 不需要其他组件支撑。顶层容器的类是Window,Window的重要子类是Frame 和Dialog。Window、Frame、Dialog和FileDialog都是一组大都含有边框, 并可以移动、放大、缩小、关闭的功能较强的容器。 非顶层容器,不是独立的窗口,它们必须位于窗口之内,非顶层容器包括 Panel及ScrollPane等。Panel必须放在Window组件中才能显示,它为一矩形 区域,在其中可摆放其他组件,可以有自己的布局管理器。 Panel的重要子类是Applet类。其中,Panel和Applet的容器都是无边框的; ScrollPane是可以自动处理滚动操作的容器。 容器类的特点是:容器中可以容纳其他组件,使用add()方法,可以将其他 对象加入到容器中。加入到容器中后,组件的位置和尺寸由布局管理器决定。 常用的Container类的方法如下: 1.add(Component comp):将指定组件放到容器中 2.remove(Component comp):删除指定组件 3.setLayout(LayoutManager mgr): 设置容器布局

Java语言基础课件线程

Java语言基础课件线程
➢ 使用步骤
1. 实现run方法 2. 把新线程要做的事写在run方法中 3. 创建自定义的Runnable的子类对象创建Thread对象, 传入Runnable 4. 调用start()开启新线程, 内部会自动调用Runnable的run()方法
实现Runnable的原理(了解)
两种方式的区别 (掌握)
子线程 主线程
线程实现的方式 (1) - 继承Thread
➢ 使用步骤 1. 定义类继承Thread 2. 重写run方法 3. 把新线程要做的事写在run方法中 4. 创建线程对象 5. 开启新线程, 内部会自动执行run方法 注:这种方式只能调用start,内部会调用run方法
线程实现的方式 (2) - 定义类实现Runnable接口
Java命令会启动java虚拟机,启动JVM,等于启动了一个应用程序,也就是启动了一个进程。该进程会自动启 动一个 “主线程” ,然后主线程去调用某个类的 main 方法。
➢ JVM的启动是多线程的吗
JVM启动至少启动了垃圾回收线程和主线程,所以是多线程的。 案例:垃圾回收和主线程打印的顺序不一样,多线程是抢占资源
多线程的概念
➢ 什么是线程
线程是程序执行的一条路径, 一个进程中可以包含多条线程 一个应用程序可以理解成就是一个进程 多线程并发执行可以提高程序的效率, 可以同时完成多项工作
➢ 多线程的应用场景
VNC同时共享屏幕给多个电脑 迅雷开启多条线程一起下载 QQ同时和多个人一起视频 服务器同时处理多个客户端请求
注意:案例中线程给个小睡眠时间
加入线程、礼让线程、设置线程优先级(了解)
join(), 当前线程暂停, 等待指定的线程执行结束后, 当前线程再继续 join(int), 可以等待指定的毫秒之后继续 yield() 让出cpu setPriority()设置线程的优先级

Java语言程序设计第8章

Java语言程序设计第8章

new Thread(t).start();
System.out.println(
"new thread started,main thread ends " );
} // end main
}
11
// class FactorialThread controls thread execution
class FactorialThread implements Runnable { private int num;
} // end main
}
4
// class FactorialThread controls thread execution class FactorialThread extends Thread {
private int num; public FactorialThread( int num ) { this.num=num; } public void run() { int i=num;
//第二个参数为新线程命名并启动之
new Thread(thread1,"Thread1").start();
new Thread(thread2,"Thread2").start();
new Thread(thread3,"Thread3").start();
System.out.println( "Threads started, main ends\n" );
本讲内容
线程基础
线程的概念 Thread类 Runnable接口 资源共享和线程同步 线程间的通信
线程的生命周期 线程的优先级 程序举例

Java语言程序设计课件第8章Java多线程编程

Java语言程序设计课件第8章Java多线程编程

8.2.2 实现RUNNABLE接口
• 如果要创建的线程类已经有一个父类,这时就不能再继承Thread类,因为Java不支 持多继承,所以需要实现Runnable接口来应对这样的情况。
• 实现Runnable接口的语法格式如下:
• public class thread extends Object implements Runnable
• 自定义线程类中的实例变量针对其他线程可以有共享与不共享之分,这在多个线程 之间进行交互时是很重要的一个技术点。
• 在不共享数据时每个线程都拥有自己作用域的变量,且多个线程之间相同变量名的 值也不相同。
• 共享数据的情况就是多个线程可以访问同一个变量,比如在实现投票功能的软件时, 多个线程可以同时处理同一个人的票数。
Java语言的特点就是单根继承,所以为了支持多继承,完全可以实现Runnable接口 的方式,一边实现一边继承。
8.2.1 继承THREAD类
• 构造方法
方法 Thread() Thread(String name) Thread(Runnable target)
Thread(Runnable target, String name)
• 在Java中,并发机制非常重要,但并不是所有程序语言都支持线程。在以往的程序 中,多以一个任务完成以后再进行下一个任务的模式进行,这样下一个任务的开始 必须等待前一个任务的结束。
• Java语言提供了并发机制,允许开发人员在程序中执行多个线程,每个线程完成一 个功能,并与其他线程并发执行。这种机制被称为多线程。
8.4 JAVA多线程的同步机制
• 如果程序是单线程的,就不必担心此线程在执行时被其他线程“打扰”,就像在现实 世界中,在一段时间内如果只能完成一件事情,不用担心做这件事情被其他事情打 扰。但是,如果程序中同时使用多线程,好比现实中的“两个人同时通过一扇门”, 这时就需要控制,否则容易引起阻塞。

JAVA电子教案--第8章

JAVA电子教案--第8章
1.线程的4种状态 在Java语言中,Thread类及其子类创建的对象称作线 程,新建的线程在它的一个完整的生命周期中通常要 经历4种状态,
(1)新建 (2)运行
线程创建后仅仅是占有了内存资源,在JVM管理的线 程中还没有这个线程,此线程必须调用start()方法 (从父类继承的方法)通知JVM,这样JVM就会知道又 有一个新一个线程排队等候切换了。
(c)线程使用CPU资源期间,执行了wait()方法,使得 当前线程进入等待状态。等待状态的线程不会主动 进到线程队列中排队等待CPU资源,必须由其他线程 调用notify()方法通知它,使得它重新进到线程队 列中排队等待CPU资源,以便从中断处继续运行。有 关wait、noftify和notifyAll方法将在第8节详细讨 论
现在,我们看一个完整的例子,通过分析运行结果阐 述线程的4种状态。该例子中我们用Thread的子类: WriteWordThread创建了两个线程。
上述程序在不同的计算机运行或在同一台计算机反复 运行的结果不尽相同,输出结果依赖当前CPU资源的使 用情况。为了使结果尽量不依赖于当前CPU资源的使用 情况,我们应当让线程主动调用sleep方法让出CPU的 使用权进入中断状态,如下列代码所示:
在线程没有结束run方法之前,不要让线程 再调用start方法,否则将发生 ILLegalThreadStateException异常。
(3)中断
有4种原因的中断:
(a) JVM将CPU资源从当前线程切换给其他线程,使本 线程让出CPU的使用权处于中断状态。
(b)线程使用CPU资源期间,执行了sleep(int millsecond)方法,使当前线程进入休眠状态。 sleep(int millsecond)方法是Thread类中的一个类 方法,线程一旦执行了sleep(int millsecond)方法, 就立刻让出CPU的使用权,使当前线程处于中断状态。 经过参数millsecond指定的豪秒数之后,该线程就 重新进到线程队列中排队等待CPU资源,以便从中断 处继续运行。

Java线程

Java线程

Java线程Java线程本教程来源互连网,仅供学习,版权归原作者及其出版商所有。

Java线程第一章关于本教程本教程有什么内容?本教程研究了线程的基础知识—线程是什么、线程为什么有用以及怎么开始编写使用线程的简单程序。

我们还将研究更复杂的、使用线程的应用程序的基本构件—如何在线程之间交换数据、如何控制线程以及线程如何互相通信。

我应该学习这个教程吗?本教程适用于拥有丰富 Java 语言应用知识,但又没有多少多线程或并发性经验的 Java 程序员。

学习完本教程之后,您应该可以编写一个使用线程的简单程序。

您还应该可以阅读并理解以简单方法使用线程的程序。

关于作者Brian Goetz 是 developerWorks Java 技术专区的一名定期专栏作家,而且他在过去的 15 年里一直是专业软件开发人员。

他是 Quiotix 的首席顾问,这是一家位于加利福尼亚州洛斯阿尔托斯市(Los Altos)的软件开发和咨询公司。

在流行的业界出版物上可以看到 Brian 发表和即将发表的文章。

可以通过brian@联系 Brian。

Java线程第二章线程基础什么是线程?几乎每种操作系统都支持进程的概念——进程就是在某种程度上相互隔离的、独立运行的程序。

线程化是允许多个活动共存于一个进程中的工具。

大多数现代的操作系统都支持线程,而且线程的概念以各种形式已存在了好多年。

Java 是第一个在语言本身中显式地包含线程的主流编程语言,它没有把线程化看作是底层操作系统的工具。

有时候,线程也称作轻量级进程。

就象进程一样,线程在程序中是独立的、并发的执行路径,每个线程有它自己的堆栈、自己的程序计数器和自己的局部变量。

但是,与分隔的进程相比,进程中的线程之间的隔离程度要小。

它们共享内存、文件句柄和其它每个进程应有的状态。

进程可以支持多个线程,它们看似同时执行,但互相之间并不同步。

一个进程中的多个线程共享相同的内存地址空间,这就意味着它们可以访问相同的变量和对象,而且它们从同一堆中分配对象。

JAVA:线程的介绍

JAVA:线程的介绍

启动线程,JVM将调用此线程的run方法,结 果是将同时运行两个线程,当前线程和执行 run方法的线程
Thread的子类应该重写此方法,内容应为该 线程应执行的任务。 停止线程运行,释放该线程占用的对象锁旗 标。 中断此线程 如果此前启动了线程A,调用join方法将等待 线程A死亡才能继续执行当前线程
Java语言程序设计(第2版),郑莉,清华大学
10
8.1 多线程编程基础
8.1.2 Thread类(续)
——例8-1修改后运行结果
• 修改后运行结果
main thread starts new thread stared The factorial of 10 is 3628800 new thread ends main thread ends
Java语言程序设计(第2版),郑莉,清华大学
16
8.1 多线程编程基础
8.1.2 Thread类(续)
——例8-2运行结果
• 运行结果 Starting threads Threads started, main ends
thread1 going to sleep for 3519 thread2 going to sleep for 1689 thread3 going to sleep for 5565 thread2 finished thread1 finished thread3 finished • 说明 ▫ 由于线程3休眠时间最长,所以最后结束,线程2休眠时间 最短,所以最先结束 ▫ 每次运行,都会产生不同的随机休眠时间,所以结果都不 相同
多数程序设计语言支持多线程要借助于操作系 统“原语(primitives)”
Java语言程序设计(第2版),郑莉,清华大学
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

//8.1public class CountingThread extends Thread{ public void run(){ System.out.println("Thread started: " + this);for (int i = 0; i <8; i++)System.out.print(this.getName()+".i = " + (i+1) + "\n");System.out.println("Thread stopped: " + this);}}public class ThreadTest{ public static void main(String args[]){ System.out.println("Starting ThreadTest");CountingThread thread1 = new CountingThread();thread1.start();CountingThread thread2 = new CountingThread();thread2.start();CountingThread thread3 = new CountingThread();thread3.start();System.out.println("ThreadTest is done.");}}run:Starting ThreadTestThread started: Thread[Thread-0,5,main]ThreadTest is done.Thread-0.i = 1Thread-0.i = 2Thread-0.i = 3Thread-0.i = 4Thread-0.i = 5Thread-0.i = 6Thread-0.i = 7Thread-0.i = 8Thread started: Thread[Thread-2,5,main]Thread stopped: Thread[Thread-0,5,main]Thread-2.i = 1Thread-2.i = 2Thread-2.i = 3Thread started: Thread[Thread-1,5,main]Thread-2.i = 4Thread-1.i = 1Thread-2.i = 5Thread-1.i = 2Thread-2.i = 6Thread-1.i = 3Thread-2.i = 7Thread-1.i = 4Thread-2.i = 8Thread-1.i = 5Thread stopped: Thread[Thread-2,5,main]Thread-1.i = 6Thread-1.i = 7Thread-1.i = 8Thread stopped: Thread[Thread-1,5,main]成功构建(总时间: 0 秒)//8.2import java.awt.*;import java.awt.event.*;public class Bird extends Thread{ private int xdir = 2*(1-2*(int)Math.round(Math.random()));private int ydir = 2*(1-2*(int)Math.round(Math.random()));private boolean running = false;private Cage cage = null;protected int x,y;// privateImage bird= Toolkit.getDefaultToolkit().getImage("c:\\Documents and Settings\\Administrator\\My Documents\\NetBeansProjects\\08\\src\\bird.jpg");public Bird(Cage _cage, int _x, int _y){ cage = _cage;x = _x;y = _y;start();}public void start(){ running = true;super.start();}public void halt(){running = false;}public void run(){while (running){move();try{ sleep(120);}catch (InterruptedException ie){ System.err.println("Thread interrupted");}cage.repaint();//this.draw();}}private void move(){x+=xdir;y+=ydir;if (x > cage.getSize().width-30){ x = cage.getSize().width-30;xdir *= (-1);}if (x < 0)xdir *= (-1);if (y > cage.getSize().height-40){y =cage.getSize().height-40;ydir *= (-1);}if (y < 30)ydir *= (-1);}public void draw(Graphics g){// g.setColor(Color.red);g.drawImage(bird,x,y,30,40,cage);//g.fillOval(x, y, 30, 30);}}import java.awt.*;import java.awt.event.*;public class Cage extends Frame implements ActionListener{ private Button quit = new Button("Quit");private Button start = new Button("Start");private Button stop = new Button("Stop");private Bird birds[] = new Bird[20];// Image bird= Toolkit.getDefaultToolkit().getImage("bird.jpg");public Cage(){ super("Cage with Birds");setLayout(new FlowLayout());add(quit); quit.addActionListener(this);add(start); start.addActionListener(this);add(stop); stop.addActionListener(this);validate(); setSize(300,300);setVisible(true);for (int i = 0; i < birds.length; i++){ int x = (int)(getSize().width*Math.random());int y = (int)(getSize().height*Math.random());birds[i] = new Bird(this,x,y);}}public void actionPerformed(ActionEvent ae){ if (ae.getSource() == stop)for (int i = 0; i < birds.length; i++)birds[i].halt();if (ae.getSource() == start)for (int i = 0; i < birds.length; i++){ // birds[i].halt();birds[i] = new Bird(this, birds[i].x, birds[i].y);}if (ae.getSource() == quit)System.exit(0);}public void paint(Graphics g){ for (int i = 0; i < birds.length; i++)if (birds[i] != null)birds[i].draw(g);}public static void main(String args[] ){ Cage table = new Cage(); }}//8.3import java.awt.*;import java.util.Date;public class ShowSeconds extends Frame implements Runnable { private Thread clocker = null;private Date now;Label l=new Label(" ");//= new Date()public ShowSeconds(){ add(l);clocker = new Thread(this);clocker.start();setSize(100,100);//pack();setVisible(true);}public void run(){ while (true){ now = new Date();System.out.println(now);l.setText(now.toString());try{ clocker.sleep(1000); }catch(InterruptedException ie){ System.err.println("Thread error: " + ie); } }}public static void main(String args[]){ ShowSeconds time = new ShowSeconds(); } }//8.4public class CorruptedData1{ protected static int DISPLAY = 1, CHANGE = 2;private WorkThread slowWorker = null;private WorkThread fastWorker = null;// private int number = 0;public CorruptedData1(){ // number = (int)(10*Math.random());slowWorker = new WorkThread(DISPLAY);fastWorker = new WorkThread(CHANGE);}public static void main(String args[]){ CorruptedData1 cd = new CorruptedData1(); } }//publicclass WorkThread extends Thread{ protected static int DISPLAY = 1, CHANGE = 2; // private CorruptedData data = null;static int number = 0;private int work = 0;public WorkThread(int _work){ //data = _data;work = _work;start();number = (int)(10*Math.random());}public void run(){ // data.performWork(work);performWork(work);}public void performWork(int type)// public void performWork(int type){ if (type == DISPLAY){ System.out.println("Number before sleeping: " + number);try{ sleep(2000);}catch(InterruptedException ie){ System.err.println("Error: " + ie); }System.out.println("Number after waking up: " + number);}if (type == CHANGE)number = -1;}}run:Number before sleeping: 5Number after waking up: -1成功构建(总时间: 2 秒)run:Number before sleeping: 2Number after waking up: -1成功构建(总时间: 2 秒)//8.6public class CorruptedData{ protected static int DISPLAY = 1, CHANGE = 2;private WorkThread slowWorker = null;private WorkThread fastWorker = null;private int number = 0;public CorruptedData(){ number = (int)(10*Math.random());slowWorker = new WorkThread(this, DISPLAY);fastWorker = new WorkThread(this, CHANGE);}public synchronized void performWork(int type)// public void performWork(int type){ if (type == DISPLAY){ System.out.println("Number before sleeping: " + number);try{ slowWorker.sleep(2000);}catch(InterruptedException ie){ System.err.println("Error: " + ie); }System.out.println("Number after waking up: " + number);}if (type == CHANGE)number = -1;}public static void main(String args[]){ CorruptedData cd = new CorruptedData(); }}//publicclass WorkThread extends Thread{ private CorruptedData data = null;private int work = 0;public WorkThread(CorruptedData _data, int _work){ data = _data;work = _work;start();}public void run(){ data.performWork(work);}}Number before sleeping: 8Number after waking up: 8成功构建(总时间: 2 秒)//8.5import java.awt.*;import java.awt.event.*;public class Bank extends Frame implements ActionListener{ protected final static int NUM_ACCOUNTS = 8;private final static int WASTE_TIME = 1;private int accounts[] = new int[NUM_ACCOUNTS];private Customer customer[] = new Customer[NUM_ACCOUNTS];private int counter = 0;private Label status = new Label("Transfers Completed: 0");private TextArea display = new TextArea();private Button show = new Button("Show Accounts");private Button start = new Button("Restart");private Button stop = new Button("Stop");public Bank(){ super("Mystery Money");Panel buttons = new Panel(); buttons.setLayout(new FlowLayout());buttons.add(show); show.addActionListener(this);buttons.add(start); start.addActionListener(this);buttons.add(stop); stop.addActionListener(this);setLayout(new BorderLayout());add("North", status); add("South", buttons); add("Center", display);for (int i = 0; i < accounts.length; i++)accounts[i] = 100000;start();validate(); setSize(300, 300); setVisible(true);addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent we){ System.exit(0); }});}//synchronized public void transfer(int from, int into, int amount){ if ((accounts[from] >= amount) && (from != into)){ int newAmountFrom = accounts[from] - amount;int newAmountTo = accounts[into] + amount;wasteSomeTime();accounts[from] = newAmountFrom;accounts[into] = newAmountTo;}status.setText("Transfers completed: " + counter++);}private void start(){ stop();for (int i = 0; i < accounts.length; i++)customer[i] = new Customer(i,this);}private void stop(){ for (int i = 0; i < accounts.length; i++)if (customer[i] != null)customer[i].halt();}private void wasteSomeTime(){ try{ Thread.sleep(WASTE_TIME); }catch(InterruptedException ie){ System.err.println("Error: " + ie); }}private void showAccounts(){ int sum = 0;for (int i = 0; i < accounts.length; i++){ sum += accounts[i];display.append("\nAccount " + i + ": $" + accounts[i]);}display.append("\nTotal Amount: $" + sum);display.append("\nTotal Transfers: " + counter + "\n");}public void actionPerformed(ActionEvent ae){ if (ae.getSource() == show)showAccounts();else if (ae.getSource() == start)start();else if (ae.getSource() == stop)stop();}public static void main(String args[]){ Bank bank = new Bank(); }}public class Customer extends Thread{ private Bank bank = null;private int id = -1;private boolean running = false;public Customer(int _id, Bank _bank){ bank = _bank;id = _id;start();}public void start(){ running = true;super.start();}public void halt(){ running = false; }public void run(){ while (running){ int into = (int)(Bank.NUM_ACCOUNTS * Math.random());int amount = (int)(1000 * Math.random());bank.transfer(id, into, amount);yield();}}}//8.5运行结果//8.7运行结果如下synchronized public void transfer(int from, int into, int amount)//8.8import java.awt.TextArea;public class DeadLockThread extends Thread{private DeadLock bank;private int id;private TextArea display;public DeadLockThread(int _id, DeadLock _bank, TextArea _display) { bank = _bank;id = _id;display = _display;start();}public void run(){while (true) {int amount = (int)(1500 * Math.random());display.append("\nThread " + S[id] + " sends $" +amount + " into " + S[(1-id)]);try{sleep(20);} catch (InterruptedException ie) {System.err.println("Interrupted");}bank.transfer(id, 1-id, amount);}}}import java.awt.*;import java.awt.event.*;import java.awt.TextArea;public class DeadLock extends Frame{protected static final String[] NAMES = {"A","B"};private int accounts[] = {1000, 1000};private TextArea info = new TextArea(5,40);private TextArea status = new TextArea(5,40);public DeadLock(){super("Deadly DeadLock");setLayout(new GridLayout(2,1));add(makePanel(info, "Accounts")); add(makePanel(status, "Threads"));validate(); pack(); setVisible(true);DeadLockThread A = new DeadLockThread(0, this, status);DeadLockThread B = new DeadLockThread(1, this, status);addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent we){ System.exit(0); }});}public synchronized void transfer(int from, int into, int amount){ info.append("\nAccount A: $" + accounts[0]);info.append("\tAccount B: $" + accounts[1]);info.append("\n=> $" + amount + " from " + NAMES[from] +" to " + NAMES[into]);while (accounts[from] < amount) {try{wait();}catch(InterruptedException ie) {System.err.println("Error: " + ie);}}accounts[from] -= amount;accounts[into] += amount;notify();}private Panel makePanel(TextArea text, String title) {Panel p = new Panel();p.setLayout(new BorderLayout());p.add("North", new Label(title)); p.add("Center", text);return p;}public static void main(String args[]){ DeadLock bank = new DeadLock(); }}Account A: $1000 Account B: $1000 => $737 from B to AAccount A: $1737 Account B: $263 => $650 from A to BAccount A: $1087 Account B: $913 => $968 from A to BAccount A: $119 Account B: $1881 => $857 from B to AAccount A: $976 Account B: $1024 => $1050 from B to AAccount A: $976 Account B: $1024 => $987 from A to BThread B sends $737 into AThread A sends $650 into BThread B sends $857 into AThread A sends $968 into BThread A sends $987 into BThread B sends $1050 into A结果2;Account A: $1000 Account B: $1000 => $905 from B to AAccount A: $1905 Account B: $95=> $1330 from A to BAccount A: $575 Account B: $1425 => $320 from A to BAccount A: $255 Account B: $1745 => $1149 from B to AAccount A: $1404 Account B: $596 => $519 from B to AAccount A: $1923 Account B: $77 => $544 from A to BAccount A: $1379 Account B: $621 => $300 from A to BAccount A: $1079 Account B: $921 => $767 from B to AAccount A: $1846 Account B: $154 => $769 from B to AAccount A: $1846 Account B: $154 => $648 from A to BAccount A: $1967 Account B: $33 => $955 from A to BAccount A: $1012 Account B: $988 => $184 from B to AAccount A: $1196 Account B: $804 => $795 from B to AAccount A: $1991 Account B: $9 => $242 from A to BAccount A: $1749 Account B: $251 => $269 from A to BAccount A: $1480 Account B: $520 => $1296 from B to AAccount A: $1480 Account B: $520 => $607 from A to BAccount A: $873 Account B: $1127 => $1031 from A to BThread B sends $905 into AThread A sends $1330 into BThread B sends $1149 into AThread A sends $320 into BThread A sends $544 into BThread B sends $519 into AThread B sends $767 into AThread A sends $300 into BThread A sends $648 into BThread B sends $769 into AThread A sends $955 into BThread B sends $184 into AThread A sends $242 into BThread B sends $795 into AThread B sends $1296 into AThread A sends $269 into BThread A sends $607 into BThread A sends $1031 into B结果3Account A: $1000 Account B: $1000 => $932 from A to BAccount A: $68 Account B: $1932 => $4 from B to AAccount A: $72 Account B: $1928 => $794 from A to BAccount A: $72 Account B: $1928 => $1080 from B to AAccount A: $358 Account B: $1642 => $914 from A to BAccount A: $358 Account B: $1642 => $1144 from B to AAccount A: $588 Account B: $1412 => $903 from B to AAccount A: $1491 Account B: $509 => $569 from A to BAccount A: $922 Account B: $1078 => $1450 from A to BAccount A: $922 Account B: $1078 => $779 from B to AAccount A: $251 Account B: $1749 => $1124 from A to BAccount A: $251 Account B: $1749 => $808 from B to AAccount A: $1059 Account B: $941 => $72 from B to AAccount A: $7 Account B: $1993 => $566 from A to BAccount A: $7 Account B: $1993 => $1181 from B to AAccount A: $622 Account B: $1378 => $156 from B to AAccount A: $778 Account B: $1222 => $840 from A to BAccount A: $778 Account B: $1222 => $940 from B to A=> $1368 from A to BAccount A: $878 Account B: $1122 => $462 from B to AAccount A: $1340 Account B: $660 => $442 from B to AAccount A: $414 Account B: $1586 => $937 from A to BAccount A: $414 Account B: $1586 => $443 from B to AAccount A: $857 Account B: $1143 => $290 from B to AAccount A: $210 Account B: $1790 => $1289 from B to AAccount A: $1499 Account B: $501 => $1256 from A to BAccount A: $243 Account B: $1757 => $111 from A to BAccount A: $132 Account B: $1868 => $1437 from B to AAccount A: $1569 Account B: $431 => $31 from A to BAccount A: $1538 Account B: $462 => $286 from B to AAccount A: $1824 Account B: $176 => $91 from A to BAccount A: $1733 Account B: $267 => $272 from B to AAccount A: $1733 Account B: $267 => $470 from A to BAccount A: $1535 Account B: $465 => $1286 from A to BAccount A: $249 Account B: $1751 => $898 from B to AAccount A: $1147 Account B: $853 => $1015 from A to BAccount A: $132 Account B: $1868 => $156 from B to AAccount A: $288 Account B: $1712 => $71 from B to AAccount A: $359 Account B: $1641 => $1255 from A to BAccount A: $359 Account B: $1641 => $1092 from B to A=> $130 from B to AAccount A: $326 Account B: $1674 => $490 from A to BAccount A: $326 Account B: $1674 => $53 from B to AAccount A: $379 Account B: $1621 => $1402 from B to AAccount A: $1291 Account B: $709 => $299 from A to BAccount A: $992 Account B: $1008 => $789 from B to AAccount A: $1781 Account B: $219 => $295 from A to BAccount A: $1486 Account B: $514 => $1189 from B to AAccount A: $1486 Account B: $514 => $1437 from A to BAccount A: $1238 Account B: $762 => $113 from A to BAccount A: $1125 Account B: $875 => $1325 from B to AAccount A: $1125 Account B: $875 => $845 from A to BAccount A: $1605 Account B: $395 => $687 from A to BAccount A: $918 Account B: $1082 => $1327 from B to AAccount A: $918 Account B: $1082 => $1332 from A to BThread B sends $4 into AThread A sends $932 into BThread A sends $794 into BThread B sends $1080 into AThread B sends $1144 into AThread A sends $914 into BThread B sends $903 into AThread A sends $569 into BThread B sends $779 into AThread A sends $1450 into BThread B sends $808 into AThread A sends $1124 into BThread B sends $72 into AThread B sends $1181 into AThread A sends $566 into B Thread B sends $156 into A Thread A sends $840 into B Thread B sends $940 into A Thread B sends $462 into A Thread A sends $1368 into B Thread B sends $442 into A Thread B sends $443 into A Thread A sends $937 into B Thread B sends $290 into A Thread B sends $1289 into A Thread A sends $1256 into B Thread B sends $1437 into A Thread A sends $111 into B Thread A sends $31 into B Thread B sends $286 into A Thread A sends $91 into B Thread B sends $272 into A Thread A sends $470 into B Thread A sends $1286 into B Thread B sends $898 into A Thread A sends $1015 into B Thread B sends $156 into A Thread A sends $1255 into B Thread B sends $71 into A Thread B sends $1092 into A Thread B sends $130 into A Thread A sends $490 into B Thread B sends $53 into A Thread B sends $1402 into A Thread B sends $789 into A Thread A sends $299 into B Thread A sends $295 into B Thread B sends $1189 into A Thread A sends $1437 into B Thread A sends $113 into B Thread B sends $1325 into A Thread A sends $845 into B Thread A sends $687 into B Thread B sends $1327 into A Thread A sends $1332 into B。

相关文档
最新文档