第七章 多线程程序设计ppt课件_第1页
第七章 多线程程序设计ppt课件_第2页
第七章 多线程程序设计ppt课件_第3页
第七章 多线程程序设计ppt课件_第4页
第七章 多线程程序设计ppt课件_第5页
已阅读5页,还剩44页未读 继续免费阅读

下载本文档

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

文档简介

第七章多线程程序设计,7.1线程的概念7.2Java线程的创建7.3线程状态和线程控制7.4线程优先级和线程的调度7.5线程同步7.6线程的死锁,7.1线程的概念,进程:一个执行中的程序,有自己独立的内存空间等系统资源。线程:程序中单个顺序的流控制,单个程序中多个线程共享系统资源。多线程编程:将任务分成多个并发的子任务。Java支持多线程。,7.2Java线程的创建,继承Thread类的方法实现Runnable接口的方法线程体有run方法(一般是一个循环,需要以线程方式运行的代码),1继承Thread类的方法,通过实现Thread类的子类、并置换其中的run()方法定义线程体,然后创建该子类的对象创建线程。如:publicclassCounterextendsThreadpublicvoidrun()/定义线程的行为启动线程CounterthreadCounter=newCounter();threadCounter.start();,2实现Runnable接口的方法,通过在类中实现Runnable接口,并在该类中提供run()方法的实现。如:publicclassCounterimplementsRunnablepublicvoidrun()/定义线程的行为启动线程CounterC1=newCounter();newThread(C1).start();CounterC1=newCounter();Threadt1=newThread(C1);t1.start();,3Thread类构造器和Threadgroup类,Thread类构造器:Thread()Thread(Runnable)Thread(Threadgroup,Runnable)Thread(String)Thread(Threadgroup,String)Thread(Runnable,String)Thread(Threadgroup,Runnable,String)Runnable:类的实例,调用Run()方法的对象Threadgroup:新创建的线程所属的线程组String:表示新线程的名字,3Thread类构造器和Threadgroup类,Threadgroup类(线程组):所有的线程一定属于某个线程组。属于Java.lang包。用于进行统一管理。显式:ThreadGroupmyThreadGroup=newThreadGroup(“mygroupofthreads”)隐式:新创建的线程自动的属于创建该线程的线程所在的线程组。,例线程概念例子,classPrintThreadextendsThreadprivateintsleepTime;publicPrintThread(Stringname)super(name);sleepTime=(int)(Math.random()*5000);System.out.println(Name:+getName()+;sleep:+sleepTime);,例线程概念例子,publicvoidrun()trySystem.out.println(getName()+goingtosleep);Thread.sleep(sleepTime);catch(InterruptedExceptionexception)System.err.println(exception.toString();System.out.println(getName()+donesleeping);,例线程概念例子,publicclassPrintThreadTestpublicstaticvoidmain(Stringargs)PrintThreadthread1=newPrintThread(thread1);PrintThreadthread2=newPrintThread(thread2);PrintThreadthread3=newPrintThread(thread3);PrintThreadthread4=newPrintThread(thread4);System.out.println(nStartingthreads);thread1.start();thread2.start();thread3.start();thread4.start();System.out.println(Threadsstartedn);,7.3线程状态和线程控制,线程的生命周期类Thread的常用方法控制和状态的关系例子,线程状态,1类Thread的常用方法,1类Thread的常用方法,1类Thread的常用方法,2线程的状态和控制的关系,3例子时钟,importjava.awt.Graphics;importjava.util.*;importjava.applet.Applet;publicclassClockextendsAppletimplementsRunnableThreadclockThread;publicvoidstart()if(clockThread=null)clockThread=newThread(this,Clock);clockThread.start();publicvoidrun()while(clockThread!=null)repaint();,3例子时钟,tryclockThread.sleep(1000);catch(InterruptedExceptione)publicvoidpaint(Graphicsg)Calendarnow=newGregorianCalendar();DatetrialTime=newDate();now.setTime(trialTime);g.drawString(now.get(Calendar.HOUR_OF_DAY)+:+now.get(Calendar.MINUTE)+:+now.get(Calendar.SECOND),5,10);publicvoidstop()clockThread=null;,3例子时钟,7.4线程优先级和线程的调度,线程的调度取决于线程的优先级。采用先占式调度,先占调度有分为:独占方式分时方式线程的优先级可以用setPriority()显式进行设置。getPriority()获得优先级。线程优先级用整数表示。从1到10,Thread.MIN_PRIORITY(1),Thread.MAX_PRIORITY(10),Thread.NORM_PRIORITY(5)例,7.4线程优先级和线程的调度画线,importjava.applet.Applet;importjava.awt.Color;publicclassRaceAppletextendsAppletimplementsRunnablefinalstaticintNUMRUNNERS=2;finalstaticintSPACING=20;Runnerrunners=newRunnerNUMRUNNERS;ThreadupdateThread=newThread(this,control);publicvoidinit()for(inti=0;iNUMRUNNERS;i+)runnersi=newRunner();runnersi.setPriority(i+1);publicbooleanmouseDown(java.awt.Eventevt,intx,inty),7.4线程优先级和线程的调度,if(!updateThread.isAlive()updateThread.start();for(inti=0;iNUMRUNNERS;i+)if(!runnersi.isAlive()runnersi.start();returntrue;publicvoidpaint(java.awt.Graphicsg)g.setColor(Color.lightGray);g.fillRect(0,0,400,500);g.setColor(Color.black);for(inti=0;iNUMRUNNERS;i+)intpri=runnersi.getPriority();g.drawString(newInteger(pri).toString(),0,(i+1)*SPACING);update(g);,7.4线程优先级和线程的调度,publicvoidupdate(java.awt.Graphicsg)for(inti=0;iNUMRUNNERS;i+)g.drawLine(SPACING,(i+1)*SPACING,SPACING+(runnersi.tick)/1000,(i+1)*SPACING);publicvoidrun()while(updateThread!=null)repaint();tryupdateThread.sleep(100);catch(InterruptedExceptione),7.4线程优先级和线程的调度,publicvoidstop()for(inti=0;iNUMRUNNERS;i+)if(runnersi.isAlive()runnersi=null;if(updateThread.isAlive()updateThread=null;ClassRunnerextendsThreadpublicinttick=1;publicvoidrun()while(tick400000)tick+;,7.5线程同步-数据的完整性,因多线程并发而引起执行顺序的不确定性,执行的不确定性会产生执行结果的不确定性。在多个线程需要共享数据时通常会产生这种不确定性。对共享对象的访问必须同步,叫做条件变量.Java语言允许通过监视器(有的参考书称其为管程)使用条件变量实现线程同步.监视器阻止两个线程同时访问同一个条件变量.它如同锁一样作用在数据上.线程1进入withdrawal方法时,获得监视器(加锁);当线程1的方法执行完毕返回时,释放监视器(开锁),线程2的withdrawal方能进入.,7.5线程同步-数据的完整性,用synchronized来标识的区域或方法即为监视器监视的部分。一个类或一个对象有一个监视器,如果一个程序内有两个方法使用synchronized标志,则他们在一个监视器管理之下.一般情况下,只在方法的层次上使用关键区,7.5线程同步-数据的完整性,此处给出的例子演示两个线程在同步限制下工作的情况.classAccountstaticintbalance=1000;/为什么用static?staticintexpense=0;publicsynchronizedvoidwithdrawl(intamount)if(amount=balance)balance-=amount;expense+=amount;elseSystem.out.println(“bounced:“+amount);,7.5线程同步-等待同步数据,可能出现的问题:生产者比消费者快时,消费者会漏掉一些数据没有取到消费者比生产者快时,消费者取相同的数据.notify()和wait()方法用来协调读取的关系.notify()和wait()都只能从同步方法中的调用.,7.5线程同步-等待同步数据,notify的作用是唤醒正在等待同一个监视器的线程.wait的作用是让当前线程等待read()方法在读信息之前先等待,直到信息可读,读完后通知要写的线程.write()方法在写信息之前先等待,直到信息被取走,写完后通知要读的进程.,例生产者/消费者例子(有同步),/HoldIntegerSynchronized.javapublicclassHoldIntegerSynchronizedprivateintsharedInt=-1;privatebooleanwriteable=true;/conditionvariablepublicsynchronizedvoidsetSharedInt(intval)while(!writeable)/nottheproducersturntrywait();catch(InterruptedExceptione)e.printStackTrace();System.err.println(Thread.currentThread().getName()+settingsharedIntto+val);,sharedInt=val;writeable=false;notify();/tellawaitingthreadtobecomereadypublicsynchronizedintgetSharedInt()while(writeable)/nottheconsumersturntrywait();catch(InterruptedExceptione)e.printStackTrace();writeable=true;notify();/tellawaitingthreadtobecomeready,System.err.println(Thread.currentThread().getName()+retrievingsharedIntvalue+sharedInt);returnsharedInt;/ProduceInteger.javapublicclassProduceIntegerextendsThreadprivateHoldIntegerSynchronizedpHold;publicProduceInteger(HoldIntegerSynchronizedh)super(ProduceInteger);pHold=h;publicvoidrun()for(intcount=1;count=10;count+)pHold.setSharedInt(count);,System.err.println(getName()+finishedproducingvalues+nTerminating+getName();/ConsumeInteger.javapublicclassConsumeIntegerextendsThreadprivateHoldIntegerSynchronizedcHold;publicConsumeInteger(HoldIntegerSynchronizedh)super(ConsumeInteger);cHold=h;publicvoidrun()intval,sum=0;doval=cHold.getSharedInt();sum+=val;,while(val!=10);System.err.println(getName()+retrievedvaluestotaling:+sum+nTerminating+getName();/SharedCell.javapublicclassSharedCellpublicstaticvoidmain(Stringargs)HoldIntegerSynchronizedh=newHoldIntegerSynchronized();ProduceIntegerp=newProduceInteger(h);ConsumeIntegerc=newConsumeInteger(h);p.start();c.start();,7.6线程的死锁,死锁:指两个或多个线程无止境地相互等待的过程。错误的同步往往会引起死锁。程序员认真设计避免死锁。如果你持有一个锁并试图获取另一个锁时,就有死锁的危险.解决死锁问题的方法:对共享资源访问的顺序,即给条件变量施加排序。,7.7多线程问题-线程间的通信,1.线程间的通信可以用管道流创建管道流:PipedInputStreampis=newPipedInputStream();PipedOutputStreampos=newPipedOutputStream(pis);或:PipedOutputStreampos=newPipedOutputStream();PipedInputStreampis=newPipedInputStream(pos);,7.7多线程问题-线程间的通信,管道流不能直接读写PrintStreamp=newPrintStream(pos);p.println(“hello”);DataInputStreamd=newDataInputStream(pis);d.readLine();管道流可以连接两个线程间的通信将一个写线程的输出通过管道流定义为读线程的输入.,7.7多线程问题-线程间的通信,主类Pipethread,辅类Writer线程类,辅类Reader线程类,管道流,将数据写到输出流,从流中读数据,输入流,作为参数传给WriterWriter(outStream),7.4多线程问题-线程间的通信,.,publicclassPipethreadpublicstaticvoidmain(Stringargs)PipethreadthisPipe=newPipethread();thisPcess();publicvoidprocess()PipedInputStreaminStream;PipedOutputStreamoutStream;PrintStreamprintOut;tryoutStream=newPipedOutputStream();inStream=newPipedInputStream(outStream);newWriter(outStream).start();newReader(inStream).start();catch(IOExceptione),7.4多线程问题-线程间的通信,classReaderextendsThreadprivatePipedInputStreaminStream;/从中读数据publicReader(PipedInputStreami)inStream=i;publicvoidrun()Stringline;DataInputStreamd;booleanreading=true;tryd=newDataInputStream(inStream);while(readingcatch(InterruptedExceptione),7.4多线程问题-线程间的通信,.,classWriterextendsThreadprivatePipedOutputStreamoutStream;/将数据输出privateStringmessages=Monday,Tuesday,Wednsday,Thursday,Friday:,Saturday:,Sunday:;publicWriter(PipedOutputStreamo)outStream=o;publicvoidrun()PrintStreamp=newPrintStream(outStream);for(inti=0;imessages.length;i+)p.println(messagesi);p.flush();System.out.println(WrIte:+messagesi);p.close();p=null;,小结,线程概念线程状态及线程控制线程优先级和线程调度线程同步线程通信读写程序,习题,什么是线程?线程和进程的区别。创建线程有哪些方法,如何使用?线程有哪几种状态?是如何进行控制的?请编写一个程序,实现在一分钟后显示当时的时间。当我们编译下面的代码时,会发生什么情况?,习题,PublicclassRuntimplementsRunnablepublicstaticvoidmain(Stringargs)Runtr1=newRunt();Threadt=newThread(r1);t.start();publicvoidstart()for(inti=0;i100;i+)System.out.println(i);,习题,创建两个线程的实例,分别将一个数组从小到大和从大到小排列.输出结果.当我们编译运行下面的代码时,会发生什么情况?PublicclassTGoimplementsRunnablepublicstaticvoidmain(Stringargs)TGor1=newTGo();Threadt=newThread(r1);t.start();publicvoidrun()while(true)Thread.currentThread().sleep(1000);System.out.println(loopingwhile);,publicclassThreadTestpublicstaticvoidmain(Stringargs)inta=2

温馨提示

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

评论

0/150

提交评论