java_8多线程_课件2016-xhu_第1页
java_8多线程_课件2016-xhu_第2页
java_8多线程_课件2016-xhu_第3页
java_8多线程_课件2016-xhu_第4页
java_8多线程_课件2016-xhu_第5页
已阅读5页,还剩49页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第八章 多线程机制,8.1 Java多线程机制 (概念掌握,理解性内容)8.2 多线程的实现方法(重点及难点)8.3 多线程状态及调度(重点)8.4 线程同步8.5 线程通信,1,8.1 Java多线程机制,8.1.1 线程的基本概念线程的概念:线程就是应用程序中的一个可执行线索,多线程就是同一个应用程序中有多个可执行线索,它们可以并发执行。 为什么要有多线程?线程与进程的区别:可否独立运行?内存空间?,2,案例,用程序来模拟铁路售票系统,实现通过四个售票点发售某日某次列车的100张车票,要求这四个售票点同时售票。这就需要一个程序能够同时执行4个任务。,3,所需要的知识点,什么是多线程如何实现多线程如何调度和控制多线程,4,多线程概述,大多数程序设计时,习惯上考虑该程序如何从头至尾顺序执行各项任务的设计方法,即一个程序只有一条执行路线。但现实世界中的很多过程都是同时发生的,对应这种情况,可编写有多条执行路径的程序,使得程序能够同时执行多个任务。,5,线程的基本概念,线程是程序中的一条执行路径。多线程是指程序中包含多条执行路径。在一个程序中可以同时运行多个不同的线程来执行不同的任务。,6,多线程基本概念,7,多线程的例子,浏览器程序聊天程序,8,进程:简单地说,在多任务系统中,每个独立执行的程序称为进程,也就是“正在运行的程序”。 线程:进程中程序代码的一个执行序列。线程并不是程序,它自己本身并不能运行,必须在程序中运行。在一个程序中可以实现多个线程,这些线程同时运行,完成不同的功能。,进程与线程,9,线程与进程的区别,进程和线程相比,主要有以下区别:两者的粒度不同,是两个不同层次上的概念。进程是由操作系统来管理的,而线程则是在一个程序(进程)内。不同进程的代码、内部数据和状态都是完全独立的,而一个程序内的多线程是共享同一块内存空间和同一组系统资源,有可能互相影响。线程本身的数据通常只有寄存器数据,以及一个程序执行时使用的堆栈,所以线程的切换比进程切换的负担要小。,10,分时操作系统,可以同一时间执行多个程序的操作系统CPU只是将时间切割为时间片,然后将时间片分配给这些程序,获得时间片的程序开始执行,不等执行完毕,下个程序又获得时间片开始执行,给人的感觉就像是多个程序在同时执行一样。 Java的多线程就是在操作系统每次分时给Java程序一个时间片的CPU时间内,在若干独立的可控制的线程之间切换。,11,多线程编程的优点,减轻编写交互频繁、涉及面多的程序的困难程序的吞吐量会得到改善由多个处理器的系统,可以并发运行不同的线程。(否则,任何时刻只有一个线程在运行),12,多线程机制,一个建立线程的例子:,public class SimpleRunnable implements Runable private String message;public static void main(String args) SimpleRunnable r1=new SimpleRunnable(Hello); Thread t1=new Thread(r1); t1.start(); public SimpleRunnable(String message) this.message = message; public void run() for(;) System.out.println(message); ,线程开始执行时,它在public void run()方法中执行。该方法是定义的线程执行起点,像应用程序从main()开始一样。,首先main()方法构造SimpleRunnable类的实例。实例有自己的一个String数据,初始化为Hello。由实例r1传入Thread类构造器,这是线程运行时处理的数据。执行的代码是实例方法run()。,13,8.2 多线程的实现方法,重点与要点:两种实现方法创建Thread子类生成一个类,声明实现Runnable接口,14,创建Thread类的子类,用这种方法生成新线程,可以按以下步骤进行:,生成Thread类的子类。 class MyThread extends Thread在子类中覆盖run()方法。 public void run()生成子类的对象,并且调用start()方法启动新线程。 MyThread thread = new MyThread(); thread.start(); start()方法将调用run()方法执行线程。,15,实现Thread子类方法的多线程示例,class FirstThread extends Thread public void run() try System.out.println(First thread starts running.); for(int i=0; i6; i+) System.out.println(First + i); sleep(1000); System.out.println(First thread finishes running.); catch (InterruptedException e) ,16,实现Thread子类方法的多线程示例,class SecondThread extends Thread public void run() try System.out.println(tSecond thread starts running.); for(int i=0; i6; i+) System.out.println(tSecond + i); sleep(1000); System.out.println(tSecond thread finishes running); catch (InterruptedException e) ,17,实现Thread子类方法的多线程示例,public class ThreadTest1 public ThreadTest1() FirstThread first = new FirstThread(); SecondThread second = new SecondThread(); first.start(); second.start();public static void main(String args) new ThreadTest1();,结果为:First thread starts running.First 0 Second thread starts running. Second 0First 1 Second 1First 2 Second 2First 3 Second 3First 4 Second 4First 5 Second 5First thread finishes running. Second thread finished.,18,Thread子类线程小结(加深理解),需要深入理解线程的run()以及start()方法:start()方法将调用run()方法执行线程。run()方法就是新线程完成具体工作的地方。注意通过对比加深了解:程序的入口, main() 方法。线程的入口, run() 方法。 Applet的入口,init()方法。,19,案例的实现,现在我们试着编程来模拟铁路售票系统。通过四个售票点发售某日某次列车的100张车票,一个售票点用一个线程来表示。用创建Thread类的子类实现多线程。,20,class SailThread extends Threadstatic int x=0; int bh;public SailThread(int n)bh=n; public void run()while(x=99) try System.out.println(“第”+bh+“号窗口正在卖出第+(+x)+张票); sleep(500); catch(InterruptedException e) ,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(); ,22,23,8.多线程实现方法,2实现Runnable接口什么是Runnable接口?Runnable是java.lang包中的一个接口。定义了创建和执行线程的功能。定义了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); thread1.start();,25,实现Runnable接口多线程示例,class FirstThread implements Runnable public void run() try System.out.println(First thread starts running.); for(int i=0; i6; i+) System.out.println(First + i); Thread.sleep(1000); System.out.println(First thread finishes running.); catch (InterruptedException e) class SecondThread implements Runnable public void run() try System.out.println(tSecond thread starts running.); for(int i=0; i6; i+) System.out.println(tSecond + i); Thread.sleep(1000); System.out.println(tSecond thread finished.); catch(InterruptedException e) ,26,实现Runnable接口多线程示例,public class RunTest public RunTest() FirstThread first = new FirstThread(); SecondThread second = new SecondThread(); Thread thread1 = new Thread(first); Thread thread2 = new Thread(second); thread1.start(); thread2.start(); public static void main(String args) new RunTest(); ,结果为:First thread starts running.First 0 Second thread starts running. Second 0First 1 Second 1First 2 Second 2First 3 Second 3First 4 Second 4First 5 Second 5First thread finishes running. Second thread finished.,27,案例的实现,用Runnable接口来实现铁路售票程序。,28,class SailRun implements Runnableint x=0; Thread t; public void run() String bh=t.currentThread().getName(); while(x Thread类的子类。实现runnable接口相对于继承Thread类来说,具有以下优点:可以避免由于Java单继承特性带来的局限。有利于程序的健壮性,代码能够被多个线程共享,代码与数据是独立的。,32,8.3多线程状态及调度,1线程的状态 具有四种状态:新生态:已分配内在,未高度 可执行态:start( ) 阻塞态 停止态:stop( ),33,线程状态,四种状态的相关概念生命周期如下:1新建:当一个Thread类或其子类的对象被创建后,进入这个状态。这时,线程对象已被分配内存空间,其私有数据已被初始化,但该线程还未被调度,可用start()方法调度,或用stop()方法中止。新生线程一旦被调度,就将切换到可执行状态。,34,线程状态,2可运行:处于可执行环境中,随时可以被调度而执行。它可细分为两个子状态:运行状态,已获得CPU,正在执行;就绪状态,只等待处理器资源。这两个子状态的过渡由执行调度器来控制。3阻塞:由某种原因引起线程暂停执行的状态。,35,线程状态,4死亡:线程执行完毕或另一线程调用stop()方法使其停止时,进入这种停止状态。它表示线程已退出可运行状态,并且不再进入可运行状态。,36,8.3.2 线程优先级及调度,问题:线程为什么需要调度?为什么引入优先级? 应用程序中的多个线程能够并发执行,但从系统的内部来看,所有线程仍然是串行的一个一个地执行,那么如何来决定哪一个线程先执行,哪一个线程后执行呢?Java引入了优先级的概念,优先级就是线程获得CPU而执行的优先程度,优先级越高,获得CPU的权力越大,执行的机会越多,执行的时间也越长。,37,线程优先级,Java把优先级划分为10级,用1至10的整数表示,数值越大,优先级越高。在Thread类中定义了三个优先级常量:MIN_PRIORITY, MAX_PRIORITY和NORM_PRIORITY,其值分别为1, 10, 5。在为线程分配优先级时,其值应该在1至10之间,否则将出错。如果应用程序没有为线程分配优先级,则Java系统为其赋值为NORM_PRIORITY。,38,线程调度原则,调度就是分配CPU资源,确定线程的执行顺序。Java采用抢占式调度方式,即高优先级线程具有剥夺低优先级线程执行的权力。如果一个低优先线程正在执行,这时出现一个高优先级线程,那么低优先级线程就只能停止执行,放弃CPU,推回到等待队列中,等待下一轮执行,而让高优先级线程立即执行。如果线程具有相同的优先级,则按先来先服务的原则调度。,39,线程调度原则,问题:如果高优先级抢占了低优先级的线程后,一直占据CPU,低优先级的线程如何获得控制权?有两个方法可以改变这种现象:一是调用sleep()方法,暂时进入睡眠状态,从而让出CPU,使有相同优先级线程和低优先级线程有执行的机会。二是调用yield()而放弃CPU,这时和它有相同优先级的线程就有执行的机会。,40,8.3.3 线程的控制,必须了解Java程序的线程结构:每个Java程序都有一个缺省的主线程:Application,主线程是main方法执行的线索;Applet,主线程指挥浏览器加载并执行Java小程序。要想实现多线程,必须在主线程中创建新的线程对象。,41,线程的状态转换图,阻塞,死亡,可运行,suspend()sleep()wait()I/O blocking,resume()sleep time_out notify()I/O finished,新建,new语句,42,线程控制方法,Thread类定义了许多控制线程执行的方法。程序中经常使用下面的方法,对线程进行控制: start():用于调用run()方法使线程开始执行。stop(): 立即停止线程执行,其内部状态清零,放弃占用资源。suspend():暂停线程执行。线程的所有状态和资源保持不变,以后可以通过另一线程调用resume()方法来重新启动这个线程。,43,线程控制方法,resume():恢复暂停的线程,安排暂停线程执行。 sleep(): 调整Java执行时间,所需参数是指定线程的睡眠时间,以毫秒为单位。join():调用线程等待本线程执行结束。yield():暂停调度线程并将其放在等待队列末尾,等待下一轮执行,使同优先级的 其它线程有机会执行 。,44,线程控制方法,isAlive():线程处于“新建”状态时,线程调用方法返回false。当一个线程调用start()方法,并占有CPU资源后,该线程的run方法就开始运行,在线程的run方法结束之前,即没有进入死亡状态之前,线程调用isAlive()方法返回true。当线程进入“死亡”状态后(实体内存被释放),线程仍可以调用方法isAlive(),这时返回的值是false。,45,8.4 线程同步,为什么需要线程同步?多线程提高了程序的并发度,但是有时候是不安全的或者不合逻辑的。则需要多线程同步。线程同步是多线程编程的一个相当重要的技术。多线程同步控制机制:保证同一时刻只有一个线程访问数据资源。同步锁:Java用锁标志(lock flag)的手段,对被访问的数据进行同步限制,从而实现对数据的保护。把所有被保护资源都加上锁标志,线程必须取得锁标志才能访问被保护的资源。,46,线程同步,在Java中,使用修饰符synchronized来为被保护资源加锁。synchronized只能用来说明方法和代码段,不能用它来说明类和成员变量。用synchronized修饰的方法和代码段称为方法同步和代码段同步,它意味着同一时刻该方法或代码段只能被一个线程执行,其它想执行该方法或代码段的线程必须等待。方法同步仅在该方法前加上synchronized修饰符即可。,47,线程同步,同步操作是以牺牲CPU资源为代价的。正确使用同步可以减少线程间的相互干扰,提高程序的稳定性和可靠性。Java程序中多个线程可以通过消息来实现互动联系的,通常可以用notify()或notifyAll()方法唤醒其它一个或所有线程。使用wait()方法来使该线程处于阻塞状态,等待其它的线程用notify()唤醒。,48,8.5 线程通信,wait方法和notify方法是Java同步机制中重要的组成部分。结合与synchronized关键字使用,可以建立很多优秀的同步模型。同步分为类级别和对象级别,分别对应着类锁和对象锁。如果static的方法被synchronized关键字修饰,则在这个方法被执行前必须获得类锁。对象锁类似。,49,wait和notify的应用示例,import java.lang.Runnable;import java.lang.Thread;class TestThread extends Threadprivate int time = 0 ;public TestThread(Runnable r,String name) super(r,name);public int getTime() return time; public int increaseTime () return +time; public class DemoThread implements Runnablepublic DemoThread() TestThread testthread1 = new TestThread(this,1); TestThread testthread2 = new TestThre

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论