Java基础讲解--第十二讲 多线程

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

线程的生命周期
Java线程不一定是分时的,必须确保线程会不时 地给另一个线程运行的机会,可以通过在各种时 间间隔中发出的sleep()调用来做到。 sleep()调用 会给较低优先级线程一个运行的机会。 Thread Thread类的yield( )方法,可用来使具有相同优先 yield( ) 级的线程获得执行的机会。如果具有相同优先级 的其他线程是可运行的,yield( )将把调用线程放 到可运行池中并使另一个线程运行。如果没有相 同优先级的可运行线程, yield( )什么也不做。 线程可通过自然终止(正常运行run()方法后终止)、 异常终止(如调用stop()方法)两种途径进入终止状 态(Dead)。
线程的生命周期
(4)死亡 处于死亡状态的线程不具有继续运行的能 力。线程死亡的原因有二,一个是正常运 行的线程完成了它的全部工作,即执行完 run方法中的全部语句,结束了run方法。 另一个原因是线程被提前强制性地终止, 即强制run方法结束。所谓死亡状态就是线 程释放了实体,即释放分配给线程对象的 内存。
Thread 的子类创建线程
在Java语言中,用Thread类或子类创建线程对 象。这一节讲述怎样用Thread子类创建对象。 用户可以扩展 Thread类,但需要重写父类的run 方法,其目的是规定线程的具体操作,否则线程就 什么也不做,因为父类的run方法中没有任何操作 语句。 下面例子中(ThreadExample5.java)除主线程 外还有两个线程,这两个线程分别在命令行窗口的 左侧和右侧顺序地一行一行地输出字符串。主线程 负责判断输出的行数,当其中任何一个线程输出8 行后,就结束进程。本例题中用到了System类中的 类方法:exit(int n),主线程使用该方法结束整 个程序。 返回
多线程(multithreading)
线程与进程的区别: 每个进程都有独立的代码和数据空间(进 程上下文),进程之间切换的开销大。 线程作为轻量的进程,同一类线程可以共 享代码和数据空间,但每个线程有独立的 运行栈和程序计数器,因此线程切换的开 销小。
多线程(multithreading)
对线程的综合支持是Java技术的一个重要 特色.它提供了thread类、监视器和条件变 量的技术. 虽然Macintosh,Windows NT,Windows 9等 操作系统支持多线程,但若要用C或C++编 写多线程程序是十分困难的,因为它们对 数据同步的支持不充分.
线程从装入的Runnble实例的run( )方法开始执行。
多线程(multithreading)
【例1】 未使用多线程技术的记数程序。 当单击“Start”按钮时,屏幕上方的文本框 开始递增记数,从0到49。在记数过程单击 “Close”按钮不起作用,记数依然在继续; 当记数到49时,程序退出。 程序代码见Counter .java。
创建线程的方法
方法2.先声明一个实现 接口的类, 方法 先声明一个实现 Runnable 接口的类,并实现 run() 方法,然后产生一个该类的实例,对该实例的引 方法,然后产生一个该类的实例 产生一个该类的实例, 用就是适合于这个构造方法的参数 class Mythread implements Runnable{ public void run( ) {/* 实现该方法*/ } 实现该方法* } 。。。。。 Mythread r=new Mythread( ); Thread newthread=new Thread(r); newthread.start();
threadrunnabletarget该构造方法中的参数是一个runnable类型的接口因此在创建线程对象时必须向构造方法的参数传递一个实现runnable接口类的实例该实例对象称作所创线程的目标对象当线程调用start方法后一旦轮到它来享用cpu资源目标对象就会自动调用接口中的run方法接口回调这一过程是自动实现的用户程序只需要让线程调用start方法即可也就是说当线程被调度并转入运行状态时所执行的就是run方法中所规定的操作
多线程(multithreading)
多线程(multithreading)
程序:静态的计算机高级语言编写的代码。 进程:程序的一次执行。 线程:程序中的部分代码的一次执行过程。 多进程:操作系统中多个程序同时执行。 多线程:程序中多个片断同时执行。
多线程(multithreading)
许多高级程序语言支持多线程,但须调用一个附 加的程序包。而java本身就有支持多线程的包 (ng.Thread包)。 Java多线程思想是将一个虚拟的CPU封装在 ng.Thread包中,每个线程的代码通过 Thread类和虚拟的CPU打交道,而java虚拟机占 用一个进程,同时运行许多虚拟的CPU,多个虚 拟CPU之间的协调不需要程序员编码,这使得用 java编写多线程程序变得容易多了。
Java 第十二讲 多线程
本章要点
理解多线程 多线程的生命周期 线程的优先级和调度 使用Thread类创建线程 线程同步 线程守护
多线程(multithreading)
程序是一段静态的代码,它是应用软件执 行的蓝本。进程是程序的一次动态执行过 程,它对应了从代码加载、执行至执行完 毕的一个完整过程,这个过程也是进程本 身从产生、发展至消亡的过程。线程是比 进程更小的执行单位。一个进程在其执行 过程中,可以产生多个线程,形成多条执 行线索,每条线索,即每个线程也有它自 身的产生、存在和消亡的过程,也是一个 动态的概念。
线程的生命周期
现在,我们看一个完整的例子 ThreadExample.java和 ThreadExample2.java ,通过分析运行结果 阐述线程的4种状态。
线程的优先级
Java虚拟机(JVM)中的线程调度器负责管理线程,调度器 把线程的优先级分为10个级别,分别用Thread类中的类常 量表示。每个Java线程的优先级都在常数1: Thread.MIN PRIORITY 到常数10: Thread.MAX_PRIORITY 的范围内。如果没有明确地设置线程的优先级别,每个线 程的优先级都为常数5(包括主线程): Thread.NORM_PRIORITY, 线程的优先级可以通过setPriority(int grade)方法调整, 这一方法需要一个int类型参数。如果此参数不在1~10的范 围内,那么setPriority便产生一个lllegalArgumenException 异常。getPriority方法返回线程的优先级。需要注意是,有 些操作系统只能识别3个级别:1,5,10。
创建线程的方法
方法1.声明一个 类的子类, 方法 声明一个 Thread 类的子类,并覆盖 run() 方法。 方法。 class Mythread extends Thread { public void run( ) {/* 覆盖该方法*/ } 覆盖该方法 该方法* }
创建线程的方法
Thread的构造方法 Thread(); Thread(String name); Thread(Runnable target); Thread(Runnable target, String name);
线程的生命周期
1.线程的4种状态 在Java语言中,Thread类及其子类创建的对象 称作线程,新建的线程在它的一个完整的生命周 期中通常要经历4种状态, (1)新建 (2)就绪、运行 线程创建后仅仅是占有了内存资源,在JVM管 理的线程中还没有这个线程,此线程必须调用 start()方法(从父类继承的方法)通知JVM, 这样JVM就会知道又有一个新一个线程排队等候 切换了。
使用Runable接口 接口 使用
使用Thread子类创建线程的优点是:我们 可以在子类中增加新的成员变量,使线程具有 某种属性,也可以在子类中新增加方法,使线 程具有某种功能。但是,Java不支持多继承, Thread类的子类不能再扩展其他的类。
1.Runnable接口与目标对象 创建线程的另一个途径就是用Thread类直接创建线 程对象。使用Thread创建线程对象时,通常使用的 构造方法是: Thread(Runnable target), 该构造方法中的参数是一个Runnable类型的接口, 因此,在创建线程对象时必须向构造方法的参数传 递一个实现Runnable接口类的实例,该实例对象称 作所创线程的目标对象,当线程调用start方法后, 一旦轮到它来享用CPU资源,目标对象就会自动调用 接口中的run方法(接口回调),这一过程是自动实 现的,用户程序只需要让线程调用start方法即可, 也就是说,当线程被调度并转入运行状态时,所执 行的就是run()方法中所规定的操作。
线程的生命周期
(3)中断 有4种原因的中断: (a) JVM将CPU资源从当前线程切换给其他线程, 使本线程让出CPU的使用权处于中断状态。 (b)线程使用CPU资源期间,执行了sleep(int millsecond)方法,使当前线程进入休眠状态。 sleep(int millsecond)方法是Thread类中的一 个类方法,线程一旦执行了sleep(int millsecond)方法,就立刻让出CPU的使用权,使 当前线程处于中断状态。经过参数millsecond指 定的豪秒数之后,该线程就重新进到线程队列中 排队等待CPU资源,以便从中断处继续运行。
多线程(multithreading)
Java应用程序总是从主类的main方法开始执行。 当JVM加载代码,发现main方法之后,就会启动 一个线程,这个线程称作“主线程”,该线程负 责执行main方法。那么,在main方法中再创建的 线程,就称为主线程中的线程。如果main方法中 没有创建其他的线程,那么当main方法执行完最 main 后一个语句,即main方法返回时,JVM就会结束 我们的Java应用程序。如果main方法中又创建了 其他线程,那么JVM就要在主线程和其他线程之 间轮流切换,保证每个线程都有机会使用CPU资 源,main方法即使执行完最后的语句,JVM也不 会结束我们的程序,JVM一直要等到主线程中的 所有线程都结束之后,才结束我们的Java应用程 序。
多线程(multithreading)
【例2】使用线程技术的记数程序。 在记数过程中,当单击“Close”按钮时, 程序立刻会退出。 程序代码见CounterThread .java。
多线程(multithreading)
多线程的优势:
多线程是在一个程序内部同时进行的多个操作, 每个操作占用一个线程,多线程共享一些系统开 销,线程之间的切换简单,线程之间的通讯比多 进程快的多。 减轻编写交互频繁、涉及面多的程序的困难. 程序的吞吐量会得到改善. 由多个处理器的系统,可以并发运行不同的线程.( 否则,任何时刻只有一个线程在运行)

线程的生命周期
(c)线程使用CPU资源期间,执行了wait()方法, 使得当前线程进入等待状态。等待状态的线程不 会主动进到线程队列中排队等待CPU资源,必须 由其他线程调用notify()方法通知它,使得它重 新进到线程队列中排队等待CPU资源,以便从中 断处继续运行。有关wait、noftify和notifyAll 方法将在以后详细讨论 (d) 线程使用CPU资源期间,执行某个操作进入阻 塞状态,比如执行读/写操作引起阻塞。进入阻 塞状态时线程不能进入排队队列,只有当引起阻 塞的原因消除时,线程才重新进到线程队列中排 队等待CPU资源,以便从原来中断处开始继续运 行。
线程的生命周期
当JVM将CUP使用权切换给线程时,如果线程是 Thread的子类创建的,该类中的run方法就立刻 执行。所以我们必须在子类中重写父类的run方 法,Thread类中的run()方法没有具体内容,程 序要在Thread类的子类中重写run()方法来覆盖 父类的run()方法,run方法规定了该线程的具体 使命。 在线程没有结束run方法之前,不要让线程再 调用start方法,否则将发生 ILLegalThreadStateException异常。
线程的生命周期
注意: 可运行的并不一定立即开始运行 Java线程是抢占式的,但并不一定是分时的 抢占式调度模型指可能有多个线程是可运行的, 但只有一个线程在实际运行。这个线程会一直运 行,直至它不再是可运行的,或者另一个具有更 高优先级的线程成为可运行的。 线程中断状态是因为人为或系统原因必须停止运 行,以后还可以恢复运行的状态。如调用线程的 sleep()方法、线程正在等待I/O操作完成、调用 wait()方法、调用suspend()方法等均可使线程由 可运行状态进入阻塞状态。
相关文档
最新文档