第十一章 Java多线程机制
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
CCUTSOFT
JAVA程序设计 程序设计
2.每个Java程序都有一个缺省的主线程。 2.每个 每个Java程序都有一个缺省的主线程 程序都有一个缺省的主线程。 Java应用程序总是从主类的 Java应用程序总是从主类的main方法开始执 应用程序总是从主类的main方法开始执 JVM加载代码 发现main方法之后, 加载代码, 方法之后 行。当JVM加载代码,发现main方法之后,就会 启动一个线程,这个线程称作“主线程” 启动一个线程,这个线程称作“主线程”,该线 程负责执行main方法 那么, main方法的执行 方法。 程负责执行main方法。那么,在main方法的执行 中再创建的线程,就称为程序中的其它线程 程序中的其它线程。 中再创建的线程,就称为程序中的其它线程。只 有当程序中所有线程都执行完毕,JVM才会结束 有当程序中所有线程都执行完毕,JVM才会结束 Java应用程序 Java应用程序。 应用程序。
CCUTSOFT
JAVA程序设计 程序设计
11.2 Thread的子类创建线程 Thread的子类创建线程
1. 线程是Thread类或其子类创建的对象 。 线程是Thread类或其子类创建的对象 2. 编写Thread类的子类时,需要重写父类的run方法, 编写Thread类的子类时 需要重写父类的 类的子类时, 重写父类的run方法 方法, 其目的是规定线程的具体操作, 其目的是规定线程的具体操作,否则线程就什么也不 因为父类的run方法中没有任何操作语句 方法中没有任何操作语句。 做,因为父类的run方法中没有任何操作语句。
CCUTSOFT
JAVA程序设计 程序设计
3、中断 一旦线程中断,则程序在当前运行处停止,让出CPU,中断原因消失后,程序进入 一旦线程中断,则程序在当前运行处停止,让出CPU,中断原因消失后, 队列排队直到再次获得CPU的控制权时才从中断处重新运行 的控制权时才从中断处重新运行。 队列排队直到再次获得CPU的控制权时才从中断处重新运行。 有4种原因造成程序中断: 种原因造成程序中断: (1)CPU资源从当前线程切换给其他线程。 CPU资源从当前线程切换给其他线程 资源从当前线程切换给其他线程。 (2)线程执行了sleep(int 线程执行了sleep(int m)方法。 毫秒后, m)方法。m毫秒后,程序进入队列 方法 (3)线程执行了wait()方法。当其他线程调用notify()方法后,程序进入队列 线程执行了wait()方法。当其他线程调用notify()方法后, 方法 方法后 (4)线程执行期间,执行某个操作进入阻塞状态 。阻塞原因消除,程序进入队列 线程执行期间, 阻塞原因消除, 4、死亡 当线程对象释放实体时,线程进入死亡状态。 当线程对象释放实体时,线程进入死亡状态。 有2种原因让线程死亡: 种原因让线程死亡: (1) run方法正常执行完毕,线程死亡 。 run方法正常执行完毕 方法正常执行完毕, (2)线程被提前强制run()方法结束 线程被提前强制run() ()方法结束
2、运行
(1)线程创建之后就具备了运行的条件。 线程创建之后就具备了运行的条件。 具备了运行的条件 线程调用start( )方法进入队列等待运行 方法进入队列等待运行。 (2) 线程调用start( )方法进入队列等待运行。 一旦线程获得CPU控制权 线程就进入运行状态。 控制权, (3)一旦线程获得CPU控制权,线程就进入运行状态。 线程运行即开始执行run( )方法 方法。 (4)线程运行即开始执行run( )方法。 注意:Thread类的子类必须重写 注意:Thread类的子类必须重写run()方法,以完成线程的具体任务; 类的子类必须重写run()方法 以完成线程的具体任务; 方法, 在线程没有结束run()方法之前 不要再次调用start()方法 方法之前, 方法。 在线程没有结束run()方法之前,不要再次调用start()方法。
JAVA程序设计 程序设计
第十一章
Java多线程机制 Java多线程机制
CCUTSOFT
JAVA程序设计 程序设计
11.1 Java中的线程 Java中的线程
11.1.1 程序、进程与线程 程序、
(1)程序是一段静态的代码,它是应用软件执行的蓝本。 程序是一段静态的代码 它是应用软件执行的蓝本。 是一段静态的代码, 进程是程序的一次动态执行过程 是程序的一次动态执行过程。 (2)进程是程序的一次动态执行过程。
CCUTSOFT
JAVA程序设计 程序设计
例11.2
class People extends Thread { StringBuffer str; People(String s,StringBuffer str) { setName(s); //调用从Thread类继承的setName方法为线程起名字 //调用从 调用从Thread类继承的 类继承的setName方法为线程起名字 this.str=str; } public void run() { for(int i=1;i<=3;i++) { str.append(getName()+","); //将当前线程的名字尾加到str //将当前线程的名字尾加到 将当前线程的名字尾加到str System.out.println("我是 System.out.println("我是"+getName()+",字符串为:"+str); 我是"+getName()+",字符串为 字符串为:"+str); try { sleep(200); } catch(InterruptedException e){} } } }
CCUTSOFT
JAVA程序设计 程序设计
11.1.2
线程的状态与生命周期
• 1. Java中的线程都是 中的线程都是Thread类或其子类的对象。 类或其子类的对象。 中的线程都是 类或其子类的对象 • 2.线程的生命周期经历 种状态 线程的生命周期经历4种状态 线程的生命周期经历 新建 运行 死亡
中断
CCUTSOFT
JAVA程序设计 程序设计
1、新建
(1)当一个Thread类或其子类的对象被声明并创建时,新生的线程对象处于新建 当一个Thread类或其子类的对象被声明并创建时 类或其子类的对象被声明并创建时, 状态。 状态。 此时线程有了相应的内存空间和其他资源。 (2) 此时线程有了相应的内存空间和其他资源。
CCUTSOFT
JAVA程序设计 程序设计
11.3 使用Runable接口 使用Runable接口
创建线程的另一个途径就是用Thread类直接创建线程对象 创建线程的另一个途径就是用Thread类直接创建线程对象。 类直接创建线程对象。 (1)使用的构造方法是: 使用的构造方法是: Thread 线程对象 = new Thread(Runnable target); Thread( target) (2)参数target被称作所创线程的目标对象 参数target被称作 被称作所创线程的目标对象 目标对象是一个实现Runnable接口的类的实例 目标对象是一个实现Runnable接口的类的实例 (3)实现Runnable接口的类必须重写run()方法,以完成具体的线程 实现Runnable接口的类必须重写 接口的类必须重写run()方法 方法, 功能。 功能。 (4)线程对象调用start()方法后,进入队列等待执行。 线程对象调用start()方法后 进入队列等待执行。 方法后, (5)可以向不同的线程对象传递同一个目标对象,此时这些线程对 可以向不同的线程对象传递同一个目标对象, 象将共享目标对象的成员变量。 象将共享目标对象的成员变量。
它对应了从代码加载、执行至执行完毕的一个完整过程,这个过程 它对应了从代码加载、执行至执行完毕的一个完整过程, 也是进程本身从产生、发展至消亡的过程。 也是进程本身从产生、发展至消亡的过程。
(3)线程是比进程更小的执行单位。 线程是比进程更小的执行单位 是比进程更小的执行单位。
一个进程在其执行过程中,可以产生多个线程,形成多条执行线索, 一个进程在其执行过程中,可以产生多个线程,形成多条执行线索, 每条线索,即每个线程也有它自身的产生、存在和消亡的过程,也是一 每条线索,即每个线程也有它自身的产生、存在和消亡的过程, 个动态的概念。 个动态的概念。
CCUTSOFT
JAVA程序设计 程序设计
例11.2 public class Example11_2 { public static void main(String args[]) { People personOne,personTwo; StringBuffer str=new StringBuffer(); personOne=new People("张三",str); People("张三 张三",str); personTwo =new People("李四",str); People("李四 李四",str); personOne.start(); personTwo.start(); } }
wk.baidu.com
CCUTSOFT
JAVA程序设计 程序设计
例11.1
public class Example11_1 { public static void main(String args[]) { SpeakHello speakHello; SpeakNinhao speakNinhao; speakHello=new SpeakHello() ; //创建线程 //创建线程 speakNinhao=new SpeakNinhao(); speakHello.start(); speakNinhao.start(); for(int i=1;i<=12;i++) { System.out.print(" 我是主线程 "); } } } class SpeakHello extends Thread { public void run() { for(int i=1;i<=12;i++) { System.out.print(" hello "); } } } class SpeakNinhao extends Thread { public void run() { for(int i=1;i<=12;i++) { System.out.print(" 您好 "); } } }
CCUTSOFT
JAVA程序设计 程序设计
11.1.3 线程调度与优先级
(1)线程优先级分为10个级别,每个Java线程的优先级都在 线程优先级分为10个级别 每个Java线程的优先级都在 个级别, 常数1 10之间 常数1-10之间。 之间。 (2)线程的优先级可以通过setPriority(int grade)方法调整。 线程的优先级可以通过setPriority(int grade)方法调整 方法调整。 当grade不在1-10的范围内,则抛出异常 grade不在 10的范围内 不在1 的范围内, IllegalAgumenException。getPriority()返回线程的优先级 IllegalAgumenException。getPriority()返回线程的优先级。 返回线程的优先级。 (3)有些操作系统只能识别3个级别:1、5、10。 有些操作系统只能识别3个级别: 10。 (4)Java调度器的任务是使高优先级的线程能始终运行。 Java调度器的任务是使高优先级的线程能始终运行 调度器的任务是使高优先级的线程能始终运行。 (5)不提倡使用线程的优先级来保证算法的正确执行。 不提倡使用线程的优先级来保证算法的正确执行。
CCUTSOFT
JAVA程序设计 程序设计
1.Java语言支持多线程。 1.Java语言支持多线程。 语言支持多线程 操作系统采用分时管理各个进程, 操作系统采用分时管理各个进程,当机器有一 CPU时 在操作系统每次分时给Java程序的一个 个CPU时,在操作系统每次分时给Java程序的一个 时间片的CPU时间内 Java程序在若干个独立的可 时间内, 时间片的CPU时间内,Java程序在若干个独立的可 控制的线程之间快速切换。当机器有多个CPU CPU时 控制的线程之间快速切换。当机器有多个CPU时, Java程序在同一时刻获得多个时间片, Java程序 Java程序在同一时刻获得多个时间片,则Java程序 程序在同一时刻获得多个时间片 才能获得真实的多线程。 才能获得真实的多线程。