




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第9讲Java的多线程机制
一、程序、进程与线程二、线程的状态三、线程优先级与调度四、多线程实现机制五、基本的线程控制
多线程是指同时存在几个执行体,按几条不同的执行路线共同工作的情况。
Java内置对多线程的支持。一、程序、进程与线程程序:一段静态的代码。进程:是程序的一次动态执行过程,包括从代码加载、执行到执行完毕的一个完整的产生、发展到消亡的过程。线程:是比进程更小的执行单位,一个进程在执行过程中,可以产生多个线程。即每个线程都是一个动态的产生、存在和消亡的过程。多线程的优势减轻编写交互频繁、涉及面多的程序的困难.程序的吞吐量会得到改善.有多个处理器的系统,可以并发运行不同的线程.(否则,任何时刻只有一个线程在运行)线程与进程的区别多个进程的内部数据和状态都是完全独立的,而多线程是共享一块内存空间和一组系统资源,有可能互相影响.线程本身的数据通常只有寄存器数据,以及一个程序执行时使用的堆栈,所以线程的切换比进程切换的负担要小。多线程基本概念文件输入输出装置各种系统资源数据区段程序区段只有一个地方在执行文件输入输出装置各种系统资源数据区段程序区段同时有数个地方在执行传统的进程多线程的任务二、线程的状态stop()或run()结束NewThread创建状态NotRunnable不可运行状态Dead消亡状态newThread()yield()start()stop()stop()Runnable运行状态sleep()suspend()wait()resume()notify()notifyAll()创建状态(newThread)
由主线程创建线程对象
ThreadmyThread=newMyThreadClass();可运行状态(Runnable) ThreadmyThread=newMyThreadClass(); myThread.start();
满足一定的调度条件时,进入Runnable状态。不可运行状态(NotRunnable) 调用了sleep()方法;
调用了suspend()方法;
为等候一个条件变量,线程调用wait()方法;
输入输出流中发生线程阻塞;死亡状态(Dead)
线程的终止一般可通过两种方法实现:自然撤消(线程执行完)或是被停止(调用stop()方法)。三、线程优先级与调度优先级:确保重要的或时间紧迫的线程即时运行方法。调度:强制优先与公平的方法。线程调度器:按照线程的优先级决定应调度哪些线程来执行,具有高优先级的线程会在较低优先级的线程之前得到执行。线程的调度是抢先式的,如果在当前线程的执行过程中,一个具有更高优先级的线程进入就绪状态,则这个高优先级的线程立即被调度执行。对优先级相同的线程来说,调度将采用轮转法。线程优先级与调度线程优先级用数字来表示,范围从1到10,即Thread.MIN_PRIORITY到Thread.MAX_PRIORITY。一个线程的缺省优先级是5,即Thread.NORM_PRIORITY。我们可以通过下面方法获得或改变线程的优先级。
intgetPriority();voidsetPriority(intnewPriority);四、多线程实现机制Java的线程:通过java.lang.Thread类来实现。每个线程都是通过某个特定Thread对象的方法run()来完成其操作的,方法run()称为线程体。构造线程体的2种方法:定义一个线程类,它继承类Thread并重写其中的方法run();提供一个实现接口Runnable的类作为线程的目标对象,在初始化一个Thread类或者Thread子类的线程对象时,把目标对象传递给这个线程实例,由该目标对象提供线程体run()。创建多线程的方式1、Threadclass2、Runnableinterface1.publicclassmythreadextendsAppletimplementsRunnable(小应用或已经是某个类的子类时)2.继承类ThreadpublicclassmythreadextendsThread3.上述两种方法中都可用类Thread产生线程的对象Threadnewthread;4.创建并启动线程
newthread=newThread(this);newthread.start();5.run方法是运行线程的主体,启动线程时,由java直接调用publicvoidrun()6.停止线程,由小应用程序的stop调用线程的stopnewthread.stop()7sleep方法的作用,暂停线程的执行,让其它线程得到机会,sleep要丢出异常,必须抓住.Try{sleep(100)}catch(InterruptedExceptione){}例:小应用程序中不用Runnable接口仍然可以使用线程(不调用主类的方法和调用主类的方法)
importjava.applet.*;publicclassthreadextendsApplet{mythreadt1=newmythread();publicstart(){t1.start();}classmythreadextendsThread{publicvoidrun(){for(inti=0;i<4;i++)System.out.println(“”+i);{try{sleep(400);}catch(InteruptedExceptione){}}}7.2创建线程的方式publicclassmainclassextendsApplet{Ct1=newC(this);publicvoidinit(){t1.start();}publicvoidpaint(Graphicsg){g.drawString("Hello,java",10,50);}}classCextendsThread{ mainclassa; C(mainclassb) {a=b;} publicvoidrun() {while(true){a.repaint(); try{sleep(400);} catch(InterruptedExceptione){}}}isAlive:判断线程目前是否正在执行状态中
if(newthread.isAlive())newthread.stop();resume:要求被暂停得线程继续执行
suspend:暂停线程的执行
join:等待线程执行完毕
thatThread.join();被等待的那个线程不结束,当前线程就一直等待.yield:将执行的权力交给其它线程,自己到队列的最后等待.其它常用的方法某一时刻只有一个线程在执行,调度策略为固定优先级调度.newthread.setPriority(Thread.MIN_PRIORITY)级别有:MIN-PRIORITYNOM_PRIORITYMAX-PRIORITY自私的线程:有很高的优先权的线程,不主动睡眠或让出处理器控制权.线程的优先权当一个线程执行完所有语句后就自动终止,调用线程的stop()方法,也可以强制终止线程。如果希望线程正常终止,可采用标记来使线程中的run()方法退出。publicclassXyzimplementsRunnable{privatebooleantimeToQuit=false;
publicvoidrun()
{while(!timeToQuit)
{…..}//cleanupbeforerun()ends;
}publicvoidstopRunning(){timeToQuit=true;}}publicclassControlThread{privateRunnabler=newXyz();privateThreadt=newThread(r);
publicvoidstartThread(){t.start();}
publivoidstopThread(){r.stopRunning();}}暂停线程的执行等待条件满足再执行.下面的例子显示线程的挂起和唤醒小应用程序第一次开始时,线程被启动浏览器改变页面时,小应用程序的stop()方法被调用,线程被挂起.浏览器回到原来的页面时,线程被唤醒.publicvoidstart(){if(mythread==null) {mythread=newThread();mythread.start();}else{mythread.resume();}}publicvoidrun(){while(true){try{sleep(100);}catch(InterruptedExceptione){}}}publicvoidstop(){ mythread.suspend(); }.1.通过继承类Thread构造线程体classSimpleThreadextendsThread{publicSimpleThread(Stringstr){super(str);}publicvoidrun(){for(inti=0;i<10;i++){System.out.println(i+""+getName());try{sleep((int)(Math.random()*1000));}catch(InterruptedExceptione){}}System.out.println("DONE!"+getName());}}publicclassTwoThreadsTest{ publicstaticvoidmain(Stringargs[]){newSimpleThread("First").start();newSimpleThread("Second").start();}}2.通过接口构造线程体importjava.applet.*;importjava.util.*;importjava.awt.*;publicclassClockextendsAppletimplementsRunnable{ThreadclockThread;publicvoidstart(){if(clockThread==null){clockThread=newThread(this,"ClockTime");clockThread.start();}}publicvoidrun(){while(clockThread!=null){repaint();try{clockThread.sleep(1000);}catch(InterruptedExceptione){}}}publicvoidpaint(Graphicsg){Datenow=newDate();g.drawString(now.getHours()+":"+now.getMinutes()+":"+now.getSeconds(),5,10);}publicvoidstop(){clockThread.stop();clockThread=null;}}两种方法的比较使用Runnable接口 可以将CPU,代码和数据分开,形成清晰的模型;
还可以从其他类继承;
保持程序风格的一致性。直接继承Thread类 不能再从其他类继承;
编写简单,可以直接操纵线程,无需使用Thread.currentThread()。五、基本的线程控制终止线程线程执行完其run()方法后,会自然终止。通过调用线程的实例方法stop()来终止线程。测试线程状态可以通过Thread中的isAlive()方法来获取线程是否处于活动状态;线程由start()方法启动后,直到其被终止之间的任何时刻,都处于‘Alive’状态。线程的暂停和恢复sleep(timeout)方法suspend()和resume()
可以由线程自身调用suspend()方法暂停自己,也可以由其它线程调用suspend()方法暂停其执行,但是要恢复由suspend()方法挂起的线程,只能由其它线程来调用resume()方法。join()挂起当前线程。挂起的时间或者为timeout毫秒,或者挂起当前线程直至它所调用的线程终止。多线程问题---执行的顺序多个线程运行时,调度策略为固定优先级调度.级别相同时,由操作系统按时间片来分配下面给出的例子中,共运行三个线程,它们做同样的事,每次打印循环次数和自己的序列号,运行结果表明,它们并不是连续运行的.在上例中如果给某个线程赋予较高的优先权,则发现这个进程垄断控制权
thread.setPriority(Thread.MAX_PRIORITY)7.3多线程问题//多个进程运行时执行顺序是交叉的classmultithreadextendsThread{intthreadNum;publicstaticvoidmain(Stringargs[]){multithreadarray[]=newmultithread[3];for(inti=0;i<3;i++)array[i]=newmultithread(i);for(inti=0;i<3;i++)array[i].start();}
multithread(intSerialNum){ super();threadNum=SerialNum;}
publicvoidrun(){for(intj=0;j<5;j++) System.out.println(“<"+j+">+MySerialNum);System.out.println("thread"+threadNum+"bye.");}}多线程问题---如何写多线程1.分别定义不同的线程类,在各自的run方法中定义线程的工作
classmythread1extendsThread{publicvoidrun{….}}classmythread2extendsThread{publicvoidrun{….}}2.在主类中实例化各线程类,并启动线程.publicclassdemoextendsApplet{publicvoidinit(){mythreadt1=newmythread1();mythreadt2=newmythread2();t1.start();t2.start();}}多线程问题---线程间的通信线程间的通信可以用管道流,创建管道流:PipedInputStreampis=newPipedInputStream();PipedOutputStreampos=newPipedOutputStream(pis);或:PipedOutputStreampos=newPipedOutputStream();PipedInputStreampis=newPipedInputStream(pos);线程1PipedOutputStreamPipedInputStream输出流outStream输入流inStream线程2多线程问题---线程间的通信管道流不能直接读写PrintStreamp=newPrintStream(pos);p.println(“hello”);DataInputStreamd=newDataInputStream(pis);d.readLine();2.通过一个中间类来传递信息.线程2线程1中间类mssm.write(s)s=m.read()write()read()printStreamDataInputStream多线程问题--线程间的通信管道流可以连接两个线程间的通信下面的例子里有两个线程在运行,一个往外输出信息,一个读入信息.将一个写线程的输出通过管道流定义为读线程的输入.outStream=newPipedOutputStream();inStream=newPipedInputStream(outStream);newWriter(outStream).start();newReader(inStream).start();
多线程问题--线程间的通信主类Pipethread辅类Writer线程类辅类Reader线程类管道流将数据写到输出流从流中读数据输入流作为参数传给WriterWriter(outStream)7.4多线程问题--线程间的通信.publicclassPipethread{publicstaticvoidmain(Stringargs[]){PipethreadthisPipe=newPipethread();thisPcess();}publicvoidprocess(){PipedInputStreaminStream;PipedOutputStreamoutStream;PrintStreamprintOut;try{outStream=newPipedOutputStream(); inStream=newPipedInputStream(outStream); newWriter(outStream).start(); newReader(inStream).start();}catch(IOExceptione){}}}7.4多线程问题---线程间的通信classReaderextendsThread{privatePipedInputStreaminStream;//从中读数据
publicReader(PipedInputStreami){inStream=i;}publicvoidrun(){Stringline;DataInputStreamd;booleanreading=true;try{d=newDataInputStream(inStream); while(reading&&d!=null){ try{line=d.readLine(); if(line!=null){ System.out.println(”Read:"+line);} elsereading=false; }catch(IOExceptione){}}catch(IOExceptione){System.exit(0);} try{Thread.sleep(4000);} catch(InterruptedExceptione){}}}7.4多线程问题--线程间的通信.classWriterextendsThread{privatePipedOutputStreamoutStream;//将数据输出
privateStringmessages[]={"Monday","Tuesday","Wednsday", "Thursday","Friday:","Saturday:","Sunday:"};publicWriter(PipedOutputStreamo)
{outStream=o;}publicvoidrun()
{PrintStreamp=newPrintStream(outStream);for(inti=0;i<messages.length;i++){ p.println(messages[i]); p.flush(); System.out.println("WrIte:"+messages[i]);} p.close();p=null;}}多线程问题---资源协调1.数据的完整性线程1线程2线程10资源取过来加1后送回去withdrwal()withdrwal()透支余额变量多线程问题---资源协调对共享对象的访问必须同步,叫做条件变量.Java语言允许通过监视器(有的参考书称其为管程)使用条件变量实现线程同步.监视器阻止两个线程同时访问同一个条件变量.它的如同锁一样作用在数据上.线程1进入withdrawal方法时,获得监视器(加锁);当线程1的方法执行完毕返回时,释放监视器(开锁),线程2的withdrawal方能进入.withdrawal()线程1监视器线程2多线程问题---资源协调用synchronized来标识的区域或方法即为监视器监视的部分。一个类或一个对象由一个监视器,如果一个程序内有两个方法使用synchronized标志,则他们在一个监视器管理之下.一般情况下,只在方法的层次上使用关键区readwrite监视器线程1线程2多线程问题---资源协调此处给出的例子演示两个线程在同步限制下工作的情况.classAccount{staticsintbalance=1000;//为什么用static?staticsintexpense=0;publicsynchronizedvoidwithdrawl(intamount){if(amount<=balanc
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 《劳动法律法规与政策》课件
- 工程项目劳务风险评估协议
- 铁路旅客运输服务普速列车设备设施规范课件
- 《建筑预算实务》课件
- 艏艉总段的装焊船体加工与装配课件
- 铁道机车专业教学张琼洁22课件
- 四空车检查南京铁道课件
- 铁路市场营销铁路运输市场分析教学案例课件
- 《GB 17930-2016车用汽油》(2025版)深度解析
- 中国五音课件下载
- (冀教版)二年级美术下册课件-洞的联想
- 学生档案补办申请表1
- 运动医学 教学大纲
- 「红人」旅游小程序产品需求文档
- 高中英语 外研版 B3U6-第6课时-writing
- 尾矿库工程坝体施工方案
- 2022届上海市16区高三语文一模分类汇编三:文学文本阅读 试卷(原卷版+解析版)
- DB37T 3717-2019 电动汽车充电站验收规范
- TK305水喷砂方案
- 先进加工技术--水切割技术PPT
- 危废处置方案完全示范版
评论
0/150
提交评论