java多线程教学讲解课件_第1页
java多线程教学讲解课件_第2页
java多线程教学讲解课件_第3页
java多线程教学讲解课件_第4页
java多线程教学讲解课件_第5页
已阅读5页,还剩30页未读 继续免费阅读

下载本文档

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

文档简介

多线程机制1.1Java多线程机制(概念掌握,理解性内容)1.2多线程的实现方法(重点及难点)1.3多线程状态及调度(重点)1.4线程同步1.5线程通信多线程机制1.1Java多线程机制(概11.1Java多线程机制1.1.1线程的基本概念线程的概念:线程就是应用程序中的一个可执行线索,多线程就是同一个应用程序中有多个可执行线索,它们可以并发执行。

为什么要有多线程?线程与进程的区别:可否独立运行?内存空间?1.1Java多线程机制1.1.1线程的基本概念2多线程机制一个建立线程的例子:publicclassSimpleRunnableimplementsRunable{ privateStringmessage; publicstaticvoidmain(Stringargs[]){ SimpleRunnabler1=newSimpleRunnable("Hello"); Threadt1=newThread(r1); t1.start(); } publicSimpleRunnable(Stringmessage){ this.message=message; } publicvoidrun(){ for(;;){ System.out.println(message); }}线程开始执行时,它在publicvoidrun()方法中执行。该方法是定义的线程执行起点,像应用程序从main()开始一样。首先main()方法构造SimpleRunnable类的实例。实例有自己的一个String数据,初始化为"Hello"。由实例传入Thread类构造器,这是线程运行时处理的数据。执行的代码是实例方法run()。多线程机制一个建立线程的例子:publicclassSi31.2多线程的实现方法重点与要点:两种实现方法创建Thread子类生成一个类,声明实现Runnable接口1.2多线程的实现方法重点与要点:4创建Thread类的子类用这种方法生成新线程,可以按以下步骤进行:生成Thread类的子类。classMyThreadextendsThread在子类中重写run()方法。publicvoidrun()生成子类的对象,并且调用start()方法启动新线程。MyThreadthread=newMyThread();thread.start();start()方法将调用run()方法执行线程。创建Thread类的子类用这种方法生成新线程,可以按以下步骤5实现Thread子类方法的多线程示例classFirstThreadextendsThread{publicvoidrun(){try{System.out.println("Firstthreadstartsrunning."); for(inti=0;i<6;i++){ System.out.println("First"+i);sleep(1000);}System.out.println("Firstthreadfinishesrunning.");}catch(InterruptedExceptione){}}}实现Thread子类方法的多线程示例classFirstT6实现Thread子类方法的多线程示例classSecondThreadextendsThread{publicvoidrun(){try{System.out.println("\tSecondthreadstartsrunning."); for(inti=0;i<6;i++){ System.out.println("\tSecond"+i); sleep(1000);}System.out.println("\tSecondthreadfinishesrunning");}catch(InterruptedExceptione){}}}实现Thread子类方法的多线程示例classSecond7实现Thread子类方法的多线程示例publicclassThreadTest1{publicThreadTest1(){ FirstThreadfirst=newFirstThread(); SecondThreadsecond=newSecondThread(); first.start();second.start(); } publicstaticvoidmain(String[]args){ newThreadTest1(); }}结果为: Firstthreadstartsrunning. First0 Secondthreadstartsrunning. Second0 First1 Second1 First2 Second2 First3 Second3 First4 Second4 First5 Second5 Firstthreadfinishesrunning.Secondthreadfinished.实现Thread子类方法的多线程示例publicclass8Thread子类线程小结(加深理解)需要深入理解线程的run()以及start()方法:start()方法将调用run()方法执行线程。run()方法就是新线程完成具体工作的地方。注意通过对比加深了解:

程序的入口,main()方法。线程的入口,run()方法。Applet的入口,init()方法。Thread子类线程小结(加深理解)需要深入理解线程的run9创建线程的方式run方法是运行线程的主体,启动线程时,由java直接调用publicvoidrun()停止线程,由小应用程序的stop调用线程的stopthread.stop()sleep方法的作用,暂停线程的执行,让其它线程得到机会,sleep要丢出异常,必须捕获。Try{sleep(100)}catch(InterruptedExceptione){}

创建线程的方式run方法是运行线程的主体,启动线程时,由ja101.2多线程实现方法2.实现Runnable接口什么是Runnable接口?

Runnable是java.lang包中的一个接口。定义了创建和执行线程的功能。定义了run()方法,完成具体任务的地方。1.2多线程实现方法2.实现Runnable接口11实现Runnable接口实现Runnable接口的主要步骤:定义一个类实现Runnable接口,

classFirstThreadimplementsRunnable并且在该类中实现run()方法。 publicvoidrun()生成这个类的对象。

FirstThreadfirst=newFirstThread();用Thread(Runnabletarget)构造函数生成Thread对象,然后调用start()方法启动线程。

Threadthread1=newThread(first); thread1.start();实现Runnable接口实现Runnable接口的主要步骤:12实现Runnable接口多线程示例classFirstThreadimplementsRunnable{publicvoidrun(){try{System.out.println("Firstthreadstartsrunning.");for(inti=0;i<6;i++){System.out.println("First"+i);Thread.sleep(1000);}System.out.println("Firstthreadfinishesrunning.");}catch(InterruptedExceptione){}}}classSecondThreadimplementsRunnable{publicvoidrun(){try{System.out.println("\tSecondthreadstartsrunning.");for(inti=0;i<6;i++){System.out.println("\tSecond"+i);Thread.sleep(1000);}System.out.println("\tSecondthreadfinished.");}catch(InterruptedExceptione){}}}实现Runnable接口多线程示例classFirstTh13实现Runnable接口多线程示例publicclassRunTest{publicRunTest(){ FirstThreadfirst=newFirstThread(); SecondThreadsecond=newSecondThread();Threadthread1=newThread(first);Threadthread2=newThread(second);thread1.start();thread2.start();}publicstaticvoidmain(String[]args){newRunTest();}}结果为: Firstthreadstartsrunning. First0 Secondthreadstartsrunning. Second0 First1 Second1 First2 Second2 First3 Second3 First4 Second4 First5 Second5 Firstthreadfinishesrunning.Secondthreadfinished.实现Runnable接口多线程示例publicclass14两种多线程实现方法

之对比相同点:都可以实现多线程不同点:灵活性:Runnable接口较灵活。应用范围:Runnable>Thread类的子类。两种多线程实现方法之对比相同点:151.3多线程状态及调度

1.线程的状态

具有四种状态:新生态:已分配内在,未高度

可执行态:start()

阻塞态

停止态:stop()

1.3多线程状态及调度1.线程的状态16线程状态四种状态的相关概念生命周期如下:1.新建:当一个Thread类或其子类的对象被创建后,进入这个状态。这时,线程对象已被分配内存空间,其私有数据已被初始化,但该线程还未被调度,可用start()方法调度,或用stop()方法中止。新生线程一旦被调度,就将切换到可执行状态。线程状态四种状态的相关概念生命周期如下:17线程状态2.可运行: 处于可执行环境中,随时可以被调度而执行。它可细分为两个子状态:运行状态,已获得CPU,正在执行;就绪状态,只等待处理器资源。

这两个子状态的过渡由执行调度器来控制。3.阻塞: 由某种原因引起线程暂停执行的状态。线程状态2.可运行:18线程状态4.死亡:线程执行完毕或另一线程调用stop()方法使其停止时,进入这种停止状态。它表示线程已退出可运行状态,并且不再进入可运行状态。线程状态4.死亡:191.3.2线程优先级及调度

问题:线程为什么需要调度?为什么引入优先级?

应用程序中的多个线程能够并发执行,但从系统的内部来看,所有线程仍然是串行的一个一个地执行,那么如何来决定哪一个线程先执行,哪一个线程后执行呢?Java引入了优先级的概念,优先级就是线程获得CPU而执行的优先程度,优先级越高,获得CPU的权力越大,执行的机会越多,执行的时间也越长。1.3.2线程优先级及调度问题:线程为什么需要调度?为什20线程优先级Java把优先级划分为10级,用1至10的整数表示,数值越大,优先级越高。在Thread类中定义了三个优先级常量:MIN_PRIORITY,MAX_PRIORITY和NORM_PRIORITY,其值分别为1,10,5。在为线程分配优先级时,其值应该在1至10之间,否则将出错。如果应用程序没有为线程分配优先级,则Java系统为其赋值为NORM_PRIORITY。线程优先级Java把优先级划分为10级,用1至10的整数表示21线程调度原则调度就是分配CPU资源,确定线程的执行顺序。Java采用抢占式调度方式,即高优先级线程具有剥夺低优先级线程执行的权力。如果一个低优先线程正在执行,这时出现一个高优先级线程,那么低优先级线程就只能停止执行,放弃CPU,推回到等待队列中,等待下一轮执行,而让高优先级线程立即执行。如果线程具有相同的优先级,则按"先来先服务"的原则调度。线程调度原则调度就是分配CPU资源,确定线程的执行顺序。22线程调度原则问题:如果高优先级抢占了低优先级的线程后,一直占据CPU,低优先级的线程如何获得控制权?有两个方法可以改变这种现象:一是调用sleep()方法,暂时进入睡眠状态,从而让出CPU,使有相同优先级线程和低优先级线程有执行的机会。二是调用yield()而放弃CPU,这时和它有相同优先级的线程就有执行的机会。线程调度原则问题:如果高优先级抢占了低优先级的线程后,一直占231.3.3线程的控制必须了解Java程序的线程结构:每个Java程序都有一个缺省的主线程:Application,主线程是main方法执行的线索;Applet,主线程指挥浏览器加载并执行Java小程序。要想实现多线程,必须在主线程中创建新的线程对象。1.3.3线程的控制必须了解Java程序的线程结构:24线程的状态转换图阻塞死亡可运行suspend()sleep()wait()I/Oblockingresume()sleeptime_outnotify()I/Ofinished新建new语句start()Stop()Stop()Stop()线程的状态转换图阻塞死亡可运行suspend()resume25线程控制方法Thread类定义了许多控制线程执行的方法。▼程序中经常使用下面的方法,对线程进行控制:start():用于调用run()方法使线程开始执行。stop():立即停止线程执行,其内部状态清零,放弃占用资源。suspend():暂停线程执行。线程的所有状态和资源保持不变,以后可以通过另一线程调用resume()方法来重新启动这个线程。线程控制方法Thread类定义了许多控制线程执行的方法。▼26线程控制方法resume():恢复暂停的线程,安排暂停线程执行。sleep():调整Java执行时间,所需参数是指定线程的睡眠时间,以毫秒为单位。join():调用线程等待本线程执行结束。yield():暂停调度线程并将其放在等待队列末尾,等待下一轮执行,使同优先级的其它线程有机会执行。线程控制方法resume():恢复暂停的线程,安排暂停线程执27线程控制方法isAlive():判断线程目前是否正在执行状态中线程处于“新建”状态时,线程调用方法返回false。当一个线程调用start()方法,并占有CUP资源后,该线程的run方法就开始运行,在线程的run方法结束之前,即没有进入死亡状态之前,线程调用isAlive()方法返回true。当线程进入“死亡”状态后(实体内存被释放),线程仍可以调用方法isAlive(),这时返回的值是false。线程控制方法isAlive():判断线程目前是否正在执行状态281.4线程同步为什么需要线程同步?多线程提高了程序的并发度,但是有时候是不安全的或者不合逻辑的。则需要多线程同步。线程同步是多线程编程的一个相当重要的技术。多线程同步控制机制:保证同一时刻只有一个线程访问数据资源。同步锁:Java用锁标志的手段,对被访问的数据进行同步限制,从而实现对数据的保护。把所有被保护资源都加上锁标志,线程必须取得锁标志才能访问被保护的资源。1.4线程同步为什么需要线程同步?29线程同步在Java中,使用修饰符synchronized来为被保护资源加锁。synchronized只能用来说明方法和代码段,不能用它来说明类和成员变量。用synchronized修饰的方法和代码段称为方法同步和代码段同步,它意味着同一时刻该方法或代码段只能被一个线程执行,其它想执行该方法或代码段的线程必须等待。方法同步仅在该方法前加上synchronized修饰符即可。线程同步在Java中,使用修饰符synchronized来为30线程同步同步操作是以牺牲CPU资源为代价的。正确使用同步可以减少线程间的相互干扰,提高程序的稳定性和可靠性。Java程序中多个线程可以通过消息来实现互动联系的,通常可以用notify()或notifyAll()方法唤醒其它一个或所有线程。使用wait()方法来使该线程处于阻塞状态,等待其它的线程用notify()唤醒。线程同步同步操作是以牺牲CPU资源为代价的。31wait方法和notify方法是Java同步机制中重要的组成部分。结合与synchronized关键字使用,可以建立很多优秀的同步模型。同步分为类级别和对象级别,分别对应着类锁和对象锁。如果static的方法被synchronized关键字修饰,则在这个方法被执行前必须获得类锁。对象锁类似。wait方法和notify方法是Java同步机制中重要的组成32wait和notify的应用示例importjava.lang.Runnable;importjava.lang.Thread;classTestThreadextendsThread{ privateinttime=0; publicTestThread(Runnabler,Stringname){ super(r,name); } publicintgetTime(){returntime;} publicintincreaseTime(){return++time;}}publicclassDemoThreadimplementsRunnable{ publicDemoThread(){ TestThreadtestthread1=newTestThread(this,"1"); TestThreadtestthread2=newTestThread(this,"2"); testthread2.start(); testthread1.start(); } publicstaticvoidmain(String[]args){ newDemoThread(); }wait和notify的应用示例impo

温馨提示

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

评论

0/150

提交评论