多线程实用全套PPT_第1页
多线程实用全套PPT_第2页
多线程实用全套PPT_第3页
多线程实用全套PPT_第4页
多线程实用全套PPT_第5页
已阅读5页,还剩53页未读 继续免费阅读

下载本文档

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

文档简介

第十章多线程第一页,共58页。1本讲内容(nèiróng)线程的概念(gàiniàn)10.2Java中多线程的编程线程的同步与死锁第二页,共58页。线程的概念(gàiniàn)1.程序、进程和线程1>程序是为完成(wánchéng)特定任务、用某种语言编写的一组指令的集合。指一段静态的代码。2>进程是程序的一次执行过程,是系统进行调度和资源分配的一个独立单位。3>进程中的一小段程序代码称为线程。第三页,共58页。2.线程的主要特点:1>不能以一个文件名的方式独立存在在磁盘中;不能单独执行,只有在进程启动后才可启动;各线程间共享进程空间的数据(代码与数据).2>线程是比进程更小一级的执行单元。3>一个进程在其执行过程中,可以产生多个线程,形成多条执行线索。4>每个线程也有它自身的产生、存在和消亡的过程,也是一个动态的概念。5>一个线程有它自己的入口和出口,以及一个顺序执行的序列6>线程不能独立存在,必须存在于进程中,线程—线程创建、销毁(xiāohuǐ)和切换的负荷远小于进程,又称为轻量级进程(lightweightprocess)。系统负担小,主要是CPU的分配。第四页,共58页。进程是正在运行的一个程序程序:静态对象--进程:动态过程操作系统为每个进程分配一段内存空间,包括(bāokuò):代码、数据以及堆栈等资源多任务的操作系统(OS)中,进程切换对CPU资源消耗较大第五页,共58页。4.多线程1>多线程是指同时存在几个执行体,按几条不同的执行线索(xiànsuǒ)共同工作的情况。2>多线程实现单个进程中的并发计算。3>各线程间共享进程空间的数据,并利用这些共享单元来实现数据交换、实时通信与必要的同步操作。4>多线程的程序能更好地表述和解决现实世界的具体问题,是计算机应用开发和程序设计的一个必然发展趋势。第六页,共58页。进程(jìnchéng)与多线程单线程多线程进程传统进程多线程进程第七页,共58页。调度策略时间片抢占式:高优先级的线程抢占CPUJava的调度方法(fāngfǎ)同优先级线程组成先进先出队列,使用时间片策略对高优先级,使用优先调度的抢占式策略12第八页,共58页。与多线程1>Java语言的一个重要功能特点:就是内置对多线程的支持,它使得编程人员可以很方便地开发出具有多线程功能,能同时(tóngshí)处理多个任务的功能强大的应用程序。2>每个Java程序都有一个隐含的主线程每个Java程序都有一个主线程,对于APPLICATION程序,主线程是main()函数执行的线索;对于Applet程序指挥浏览器加载并执行Java小程序,要想实现多线程,必须在主线程中创建新的线程对象。3>线程的用途:利用它可以完成重复性的工作(如实现动画、声音等的播放);从事一次性较费时的初始化工作(如网络连接、声音数据文件的加载,但对图像文件*.gif、*.jpeg在java中自动地在后台载入、因而可不必设计图像载入的线程);并行的执行效果(一个进程多个线程)。第九页,共58页。要想实现线程,必须在主线程中创建新的线程对象。Java语言使用Thread类及其子类的对象来表示线程,在它的一个完整的生命周期中通常要经历如下的五种状态:1>新建:当一个Thread类或其子类的对象被声明并创建时,新生的线程对象处于新建状态2>就绪:处于新建状态的线程被启动后,将进入线程队列等待CPU时间片,此时它已具备了运行的条件3>运行:当就绪的线程被调度并获得处理器资源时,便进入运行状态,run()方法定义了线程的操作和功能4>阻塞:在某种特殊情况下,被人为挂起或执行输入输出操作时,让出CPU并临时中止自己的执行,进入阻塞状态5>死亡:线程完成了它的全部工作或线程被提前强制性地中止stop()或destroy()线程死亡不具有继续(jìxù)运行能力线程死亡有两个原因:___正常执行的线程完成它的全部工作,即执行完run()方法的最后一句并退出___线程被强制终止,如stop()方法、destroy()方法第十页,共58页。线程的生命周期第十一页,共58页。线程的生命周期(续)Newborn:线程已创建,但尚未执行Runnable:(就绪)线程已被调度,按优先级和先到先服务原则在队列中排队等待CPU时间片资源Runnnig:正在运行Blocked:(阻塞)因某事件或睡眠而被暂时性地挂起Dead:正常(zhèngcháng)/强行中断,退出运行状态第十二页,共58页。线程状态(zhuàngtài)新建状态newThread(..)就绪状态start()等待状态执行状态I/Osleep()CPU调度run()结束stop()yield()消亡

I/O完成sleep时间到第十三页,共58页。Java对多线程的支持(zhīchí)提供对多线程的支持Thread类start(),stop(),run()Runnable接口(jiēkǒu)实现多线程的两种编程方法继承Thread类实现Runnable接口(jiēkǒu)第十四页,共58页。Thread类Thread类综合了Java程序中一个线程需要拥有的属性和方法当生成一个Thread类的对象后,一个新的线程诞生了。每个线程都是通过目标对象的方法run()来完成其操作的。方法run()称为线程体(线程方法)。提供(tígōng)线程体的目标对象是在初始化一个线程时指明的。任何实现了Runnable接口(实现run()方法)的类实例都可以作为线程的目标对象。第十五页,共58页。方法(fāngfǎ)之一:继承Thread类Thread类的重要(zhòngyào)方法:run()定义线程的具体操作系统调度此线程时自动执行初始时无具体操作内容如何编程呢?-继承(jìchéng)Thread类,定义run()方法第十六页,共58页。Thread类构造函数Thread();Thread(Stringthreadname);指定线程实例名线程的优先级控制三个常量(chángliàng):MAX_PRIORITY10;MIN_PRIORITY1;NORM_PRIORITY5;getPriority()返回线程优先值setPriority(intnewPriority)改变线程的优先级线程创建时继承父线程的优先级第十七页,共58页。Thread类的有关(yǒuguān)方法voidstart():由Newborn到Runnable启动线程StringgetName():返回线程的名称run():线程在被调度时执行的操作(cāozuò)staticvoidsleep(指定时间毫秒):令当前活动线程在指定时间段内放弃对CPU控制,使其他线程有机会被执行,时间到后重排队产生例外InterruptedException用try块调用sleep(),用catch块处理例外第十八页,共58页。Thread类的有关(yǒuguān)方法(续)suspend():挂起线程,处于(chǔyú)阻塞状态resume():恢复挂起的线程,重新进入就绪队列排队应用:可控制某线程的暂停与继续方法:设一状态变量suspendStatus=false(初始)暂停:if(!suspendStatus) {T.suspend();suspendStatus=true;}继续:if(suspendStatus) {T.resume();suspendStatus=false;}第十九页,共58页。Thread类的有关(yǒuguān)方法(续)staticvoidyield():对正在执行的线程若就绪队列中有与当前线程同优先级的排队线程,则当前线程让出CPU控制权,移到队尾若队列中没有同优先级的线程,忽略此方法stop():强制线程生命期结束(jiéshù)booleanisAlive():返回boolean,表明是否线程还存在staticcurrentThread():返回当前线程

第二十页,共58页。生成与运行(yùnxíng)线程–方法1MyThreadmt=newMyThread();mt.start();

classMyThreadextendsThread{publicvoidrun(){线程体…}}执行run()方法第二十一页,共58页。建立(jiànlì)线程线程控制(虚拟CPU)线程代码被操作数据Thread类的子类的实例(mt)Thread类的子类提供的run方法Thread子类实例(mt)第二十二页,共58页。Thread类方法(fāngfǎ)总结启动(qǐdòng)线程:start()有关线程执行的控制:stop()、suspend()、resume()有关调度控制Thread.sleep(10);//低优先级的线程也可以获得执行Thread.yield();//同优先级的线程可以获得执行suspend();//暂停本线程第二十三页,共58页。for(inti=0;i<NUMRUNNERS;i++){if(updateThread.加锁1(临界区-方法)staticvoidyield():对正在执行的线程谢谢(xièxie)观看多个线程对内存、数据(shùjù)的共享,会造成操Thread(Runnable,String)同优先级线程组成先进先出队列,使用时间片策略Producerp1=newProducer(c,1);//Producer线程1>不能以一个文件名的方式独立存在在磁盘中;updateThread=newThread(this,"ThreadRace");synchronized//创建绘图线程,并设优先级为3wait();//条件不符合,则waitpublicvoidrun(){方法(fāngfǎ)之二:RunnableRunnable接口自定义类实现(shíxiàn)Runnable接口使用Thread类的另一构造函数:Thread(Runnable,String)用实现(shíxiàn)了Runnable接口的类的对象中所定义的run()方法,来覆盖新创建的线程对象的run()方法使用start()启动线程第二十四页,共58页。方法(fāngfǎ)之二:Runnable(续)例:classAimplementsRunnable{ publicvoidrun(){….}}classB{ publicstaticvoidmain(String[]arg){ Runnablea=newA(); Threadt=newThread(a); t.start(); } }第二十五页,共58页。建立(jiànlì)线程例publicclassThreadTest{publicstaticvoidmain(String[]args){Job1j=newJob1();Threadt1=newThread(j);t1.start();}}classJob1implementsRunnable{inti=1;publicvoidrun(){while(i<50){System.out.println(i++);}}}第二十六页,共58页。建立(jiànlì)线程线程控制(虚拟CPU)线程代码被操作数据Thread的实例(t1)由实现了Runnable接口的类(Job1)提供—run方法实现Runnable接口的类(Job1)的实例(j)第二十七页,共58页。

生成(shēnɡchénɡ)与运行线程–方法2classMyRunimplementsRunnable{publicvoidrun(){线程体…}}MyRunmr=newMyRun();Threadt1=newThread(mr);t1.start();//Thread实例(shílì)用于线程控制适合于:定义run()方法的类必须是其他类或其他类的子类。第二十八页,共58页。方法(fāngfǎ)之二:Runnable(续)两种方法的选择当需要从其他类,如Applet类继承时,使用Runnable接口(jiēkǒu)当编写简单的程序时,可考虑使用继承Thread类具体运行结果(线程调度)与平台有关第二十九页,共58页。publicclassRunnerextendsThread{//赛跑者线程类

publicinttick=1;publicvoidrun(){while(tick<40000000)tick++;}}//Runner.java//RaceApplet是一个实现了多线程的AppletpublicclassRaceAppletextendsAppletimplementsRunnable{finalstaticintNUMRUNNERS=2;//定义赛跑线程的个数

finalstaticintSPACING=20;

//声明两个赛跑线程

Runner[]runners=newRunner[NUMRUNNERS];

//声明一个画图线程

ThreadupdateThread=null;第三十页,共58页。publicvoidinit(){//重载Applet的init()方法(fāngfǎ)for(inti=0;i<NUMRUNNERS;i++){runners[i]=newRunner();//创建赛跑线程线程runners[i].setPriority(i+1);//设优先级first=1,second=2}if(updateThread==null){ //创建绘图线程,并设优先级为3updateThread=newThread(this,"ThreadRace");updateThread.setPriority(NUMRUNNERS+1);}addMouseListener(newMyAdapter());//注册事件监听者}//endofinit()第三十一页,共58页。//内部事件监听者类,监听鼠标事件classMyAdapterextendsMouseAdapter{//鼠标点击后,开始赛跑及绘制(huìzhì)线程publicvoidmouseClicked(MouseEventevt){if(!updateThread.isAlive())updateThread.start();//启动绘制(huìzhì)线程for(inti=0;i<NUMRUNNERS;i++){if(!runners[i].isAlive())runners[i].start();//启动赛跑线程}}}//endofclassMyAdapter第三十二页,共58页。publicvoidpaint(Graphicsg){//paint()方法中绘制(huìzhì)框架………}//endofpaint()//update()方法中绘制(huìzhì)赛跑者的进度publicvoidupdate(Graphicsg){for(inti=0;i<NUMRUNNERS;i++){//画两条线g.drawLine(SPACING,(i+1)*SPACING,SPACING+(runners[i].tick)/100000,(i+1)*SPACING);}}//endofupdate()第三十三页,共58页。publicvoidrun(){//实现Runnable接口的run()方法while(true){repaint();//重新绘制,自动调用update()方法try{Thread.sleep(10);//休眠,把执行机会(jīhuì)让给低优先级线程}catch(InterruptedExceptione){}}}//endofrun()publicvoidstop(){//重载Applet的stop()方法for(inti=0;i<NUMRUNNERS;i++){if(runners[i].isAlive())runners[i]=null;//中止赛跑线程}if(updateThread.isAlive())updateThread=null;//中止绘图线程}//endofstop()}第三十四页,共58页。线程的同步(tóngbù)与互斥问题的提出多个线程执行的不确定性引起执行结果的不稳定如线程A:A1-A2 线程B:B1-B2多个线程对内存、数据(shùjù)的共享,会造成操作的不完整性,会破坏数据(shùjù)。如push(a):i++;num[i]=a;pop():取出num[i];i--;第三十五页,共58页。线程的同步(tóngbù)与互斥问题的解决同步:用synchronized关键字前缀给针对共享资源的操作(cāozuò)加锁;同步方法、同步块synchronizedvoidpush();synchronizedintpop();临界区实现机制:管程第三十六页,共58页。线程的同步(tóngbù)与互斥对象互斥锁在Java中,每个对象有一个“互斥锁”,该锁可用来保证(bǎozhèng)在同一时刻只能有一个线程访问该对象。锁的使用过程(当一个线程要操作一个对象时)准备加锁对象是否已加锁加锁进入临界区执行操作解锁否是第三十七页,共58页。线程的同步(tóngbù)与互斥加锁1(临界区-方法)synchronized方法名{…}进入该方法时加锁加锁2(临界区-代码块)方法名{….synchronized(this){…}//进入该代码段时加锁….}一个(yīɡè)线程为某对象加锁后,便对该对象具有了监控权。第三十八页,共58页。线程的同步(tóngbù)与互斥线程间需协调与通讯(tōngxùn):生产者/消费者问题进队出队生产者消费者第三十九页,共58页。线程的同步(tóngbù)与互斥wait()与notify()Object类的方法:publicfinalvoidwait():令当前线程挂起并放弃管程,同步资源解锁,使别的线程可访问并修改共享资源,而当前线程排队等候再次对资源的访问notify()唤醒正在排队等待资源管程的线程中优先级最高者,使之执行并拥有资源的管程wait()+notify()+标志变量:可协调(xiétiáo)、同步不同线程的工作第四十页,共58页。线程的同步(tóngbù)与互斥主线程线程1()线程2()操作对象共享数据(队)synchronized同步方法1(生产)wait()notify()synchronized同步方法2(消费)wait()notify()第四十一页,共58页。线程的同步(tóngbù)与互斥publicfinalvoidwait()方法在当前(dāngqián)线程中调用方法:对象名.wait()使当前(dāngqián)线程进入等待(某对象)状态,直到另一线程对该对象发出notify(或notifyAll)为止。调用方法的必要条件:当前(dāngqián)线程必须具有对该对象的监控权(加锁)当前(dāngqián)线程将释放对象监控权,然后进入等待队列(wait队列)。在当前(dāngqián)线程被notify后,要重新获得监控权,然后从断点处继续代码的执行。第四十二页,共58页。线程的同步(tóngbù)与互斥publicfinalvoidnotify()方法在当前(dāngqián)线程中调用方法:对象名.notify()功能:唤醒等待该对象监控权的一个线程。调用方法的必要条件:当前(dāngqián)线程必须具有对该对象的监控权(加锁)notifyAll()唤醒wait队列中的所有线程,并把它门移入锁申请队列。第四十三页,共58页。线程状态(zhuàngtài)新建状态就绪状态start()等待状态执行状态CPU调度run()结束消亡等待状态对象wait()池等待状态对象lock池wait()notify()synchronized()解锁

sleep()join()yield()第四十四页,共58页。线程调度(diàodù)publicstaticvoidsleep(long

millis)当前进程休眠指定时间publicstaticvoidyield()主动让出CPU,重新排队正在执行(zhíxíng)的线程将CPU让给其他具有相同优先级的线程,自己进入就绪状态重新排队publicfinalvoidjoin()等待某线程结束第四十五页,共58页。等待(děngdài)另一线程结束Runnableot=newotheeThread();Threadtt=newThread(ot);tt.start();…//执行自己(zìjǐ)的工作try{tt.join();}catch(interruptedExceptione){}….//继续做自己(zìjǐ)的事第四十六页,共58页。终止(zhōngzhǐ)线程publicclassRimplementRunnable{privatebooleantimeToQuit=false;//设标记(biāojì)publicvoidrun(){while(!timeToQuit){…}}publicvoidstopRunning(){timeToQuit=true;}}publicclasstest{publicstaticvoidmain(String[]args){Runnabler=newR();Threadt=newThread(r);t.start();if(…)r.stopRunning();}}第四十七页,共58页。线程的同步(tóngbù)与互斥创建用户的线程子类Producer:产生数据(存数据);Consumer:消费数据(取数据)CubbyHole类,共享数据区,同步方法put(intvalue)方法intget()方法主类中创建共享数据对象(duìxiàng),并启动两线程第四十八页,共58页。classCubbyHole{privateintseq;//共享数据(shùjù)privatebooleanavailable=false;//条件标志变量publicsynchronizedintget(){//取数据(shùjù)的同步方法get() while(available==false){ try{ wait();//条件不符合,则wait }catch(InterruptedExceptione){} } available=false;//修改条件 notify();//通知唤醒其他等待管程的线程 returnseq;//返回要取出的数值}//endofget()第四十九页,共58页。//存放数据(shùjù)的同步方法put()publicsynchronizedvoidput(intvalue){ while(available==true){ try{ wait();//条件不符合,则wait }catch(InterruptedExceptione){} } seq=value;//把共享变量修改为要放置的数据(shùjù) available=true;//修改条件 notify();//通知唤醒其他等待管程的线程}//endofput()}//endofclassCubbyHole第五十页,共58页。classProducerextendsThread{//生产者线程类privateCubbyHolecubbyhole;privateintnumber;publicProducer(CubbyHolec,intnumber){cubbyhole=c;this.number=number;}publicvoidrun(){//定义(dìngyì)run()方法for(inti=0;i<10;i++){//共产生10个cubbyhole.put(i);System.out.println("Producer#"+this.number+"put:"+i);try{sleep((int)(Math.random()

温馨提示

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

评论

0/150

提交评论