Chap7-Java线程_第1页
Chap7-Java线程_第2页
Chap7-Java线程_第3页
Chap7-Java线程_第4页
Chap7-Java线程_第5页
已阅读5页,还剩88页未读 继续免费阅读

下载本文档

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

文档简介

1、第第7章章 多线程多线程电子科技大学电子科技大学计算机学院计算机学院2第第7章章 多线程多线程n7.1 多线程基本概念多线程基本概念n7.2 创建线程的方式创建线程的方式n7.3 线程的挂起与唤醒线程的挂起与唤醒n7.4 多线程问题多线程问题n7.5 小结小结37.1 多线程基本概念多线程基本概念文件文件输入输出装置输入输出装置各种系统资源各种系统资源数据区段数据区段程序区段程序区段只有一个地方在执行只有一个地方在执行文件文件输入输出装置输入输出装置各种系统资源各种系统资源数据区段数据区段程序区段程序区段同时有数个地方在执行同时有数个地方在执行传统的进程传统的进程多线程的任务多线程的任务47.

2、1 多线程基本概念多线程基本概念n多线程的优势多线程的优势:n减轻编写交互频繁、涉及面多的程序的困难减轻编写交互频繁、涉及面多的程序的困难.n程序的吞吐量会得到改善程序的吞吐量会得到改善.n由多个处理器的系统由多个处理器的系统,可以并发运行不同的线可以并发运行不同的线程程.(否则否则,任何时刻只有一个线程在运行任何时刻只有一个线程在运行)57.1 多线程基本概念多线程基本概念n线程与进程的区别线程与进程的区别:n多个进程的内部数据和状态都是完全独立多个进程的内部数据和状态都是完全独立的的,而多线程是共享一块内存空间和一组系而多线程是共享一块内存空间和一组系统资源统资源,有可能互相影响有可能互相

3、影响.n线程本身的数据通常只有寄存器数据,以线程本身的数据通常只有寄存器数据,以及一个程序执行时使用的堆栈,所以线程及一个程序执行时使用的堆栈,所以线程的切换比进程切换的负担要小。的切换比进程切换的负担要小。67.1 多线程基本概念多线程基本概念n对线程的综合支持是对线程的综合支持是Java技术的一个重要特技术的一个重要特色色.它提供了它提供了thread类、监视器和条件变量的类、监视器和条件变量的技术技术.n虽然虽然Macintosh,Windows NT,Windows 9等操等操作系统支持多线程作系统支持多线程,但若要用但若要用C或或C+编写多编写多线程程序是十分困难的,因为它们对数据同

4、线程程序是十分困难的,因为它们对数据同步的支持不充分步的支持不充分.77.2 创建线程的方式创建线程的方式1. public class mythread extends Applet implements Runnable (小应用或已经是某个类的子类时小应用或已经是某个类的子类时)2. 继承类继承类Thread public class mythread extends Thread3. 上述两种方法中都可用类上述两种方法中都可用类Thread产生线程的产生线程的对象对象 Thread newthread;4. 创建并启动线程创建并启动线程 newthread=new Thread(thi

5、s); newthread.start();87.2 创建线程的方式创建线程的方式n5. run方法是运行线程的主体方法是运行线程的主体,启动线程时启动线程时,由由java直接调用直接调用 public void run() n6.停止线程停止线程,由小应用程序的由小应用程序的stop调用线程的调用线程的stop newthread.stop() n7. sleep方法的作用方法的作用,暂停线程的执行暂停线程的执行,让其它线让其它线程得到机会程得到机会,sleep要丢出异常要丢出异常,必须抓住必须抓住.nTrysleep(100)catch(InterruptedException e) n例

6、例:小应用程序中不用小应用程序中不用Runnable接口仍然可以接口仍然可以使用线程使用线程(不调用主类的方法和调用主类的方不调用主类的方法和调用主类的方法法)n 9import java.applet.*;public class thread extends Applet mythread t1=new mythread(); public init() t1.start();class mythread extends Thread public void run() for (int i=0;i4;i+) System.out.println( “”+i); trysleep(400)

7、; catch(InteruptedException e) 7.2 创建线程的方式创建线程的方式107.2 创建线程的方式创建线程的方式public class mainclass extends Applet C t1=new C(this); public void init() t1.start(); public void paint(Graphics g) g.drawString(Hello,java,10,50);class C extends Thread mainclass a;C(mainclass b) a=b; public void run() while(true

8、) a.repaint();trysleep(400); catch(InterruptedException e) 117.2 创建线程的方式创建线程的方式8.其它常用的方法其它常用的方法 isAlive :判断线程目前是否正在执行状态中判断线程目前是否正在执行状态中 if(newthread.isAlive() newthread.stop(); resume:要求被暂停得线程继续执行要求被暂停得线程继续执行 suspend:暂停线程的执行暂停线程的执行 join:等待线程执行完毕等待线程执行完毕 thatThread.join();被等待的那个线程不结束被等待的那个线程不结束,当当前线程

9、就一直等待前线程就一直等待. yield:将执行的权力交给其它线程将执行的权力交给其它线程,自己到队列自己到队列的最后等待的最后等待.127.2 创建线程的方式创建线程的方式9.线程的优先权线程的优先权n某一时刻只有一个线程在执行某一时刻只有一个线程在执行,调度策略为固定调度策略为固定优先级调度优先级调度.newthread.setPriority(Thread.MIN_PRIORITY)n级别有级别有:MIN-PRIORITYn NOM_PRIORITYn MAX-PRIORITY10. 自私的线程自私的线程:有很高的优先权的线程有很高的优先权的线程,不主动睡不主动睡眠或让出处理器控制权眠或

10、让出处理器控制权.137.2 创建线程的方式创建线程的方式new Thread()New ThreadRunnablestart()Not Runnablestop()stop()Deadyield()stop() orrun()exit. .suspend()sleep()wait()resume().11. 线程的状态线程的状态147.2 创建线程的方式创建线程的方式n当一个线程执行完所有语句后就自动终止,调当一个线程执行完所有语句后就自动终止,调用线程的用线程的stop()方法,也可以强制终止线程。方法,也可以强制终止线程。n如果希望线程正常终止,可采用标记来使线程如果希望线程正常终止,

11、可采用标记来使线程中的中的run()方法退出。()方法退出。157.2 创建线程的方式创建线程的方式public class Xyz implements Runnable private boolean timeToQuit=false; public void run()() while (!(!timeToQuit) . /clean up before run()() ends; public void stopRunning() timeToQuit=true; 167.2 创建线程的方式创建线程的方式npublic class ControlThreadn private Runn

12、able r=new Xyz();n private Thread t=new Thread(r);n n public void startThread()n t.start(); n n publi void stopThread()n r.stopRunning();n177.3 线程的挂起与唤醒线程的挂起与唤醒n暂停线程的执行等待条件满足再执行暂停线程的执行等待条件满足再执行.n下面的例子显示线程的挂起和唤醒下面的例子显示线程的挂起和唤醒n小应用程序第一次开始时小应用程序第一次开始时,线程被启动线程被启动n浏览器改变页面时浏览器改变页面时,小应用程序的小应用程序的stop()方法方法被

13、调用被调用,线程被挂起线程被挂起.n浏览器回到原来的页面时浏览器回到原来的页面时,线程被唤醒线程被唤醒.187.3 线程的挂起与唤醒线程的挂起与唤醒public void start() if (mythread=null) mythread=new Thread(); mythread.start(); else mythread.resume();public void run() while(true) trysleep(100); catch(InterruptedException e) public void stop() mythread.suspend(); .197.4 多线

14、程问题多线程问题-执行的顺序执行的顺序n多个线程运行时多个线程运行时,调度策略为固定优先级调调度策略为固定优先级调度度.级别相同时级别相同时,由操作系统按时间片来分配由操作系统按时间片来分配n下面给出的例子中下面给出的例子中,共运行三个线程共运行三个线程,它们做它们做同样的事同样的事, 每次打印循环次数和自己的序列每次打印循环次数和自己的序列号号,运行结果表明运行结果表明,它们并不是连续运行的它们并不是连续运行的.n在上例中如果给某个线程赋予较高的优先权在上例中如果给某个线程赋予较高的优先权,则发现这个进程垄断控制权则发现这个进程垄断控制权 thread.setPriority(Thread.

15、MAX_PRIORITY)nthreadmultithread.class-f1.batnthreadPriority.class-f2.bat207.3 多线程问题多线程问题/多个进程运行时执行顺序是交叉的多个进程运行时执行顺序是交叉的class multithread extends Thread int threadNum; public static void main(String args) multithread array=new multithread3; for (int i=0;i3;i+) arrayi=new multithread(i); for (int i=0;

16、i3;i+) arrayi.start(); multithread(int SerialNum) super(); threadNum=SerialNum; public void run() for(int j=0;j5;j+)System.out.println(“ +MySerialNum); System.out.println(thread +threadNum+ bye.);217.4 多线程问题多线程问题-如何写多线程如何写多线程1.1.分别定义不同的线程类分别定义不同的线程类, ,在各自的在各自的runrun方法中方法中定义线程的工作定义线程的工作 class mythrea

17、d1 extends Thread public void run. class mythread2 extends Thread public void run. 2. 在主类中实例化各线程类在主类中实例化各线程类,并启动线程并启动线程. public class demo extends Applet public void init() mythread t1=new mythread1(); mythread t2=new mythread2(); t1.start(); t2.start(); 227.4 多线程问题多线程问题-如何写多线程如何写多线程n练习练习:将窗口分为上下两个区

18、将窗口分为上下两个区,分别运行两个分别运行两个线程线程,一个在上面的区域中显示由右向左游动一个在上面的区域中显示由右向左游动的字符串的字符串,另一个在下面的区域从左向右游动另一个在下面的区域从左向右游动的字符串的字符串.n方法一方法一: 一个线程一个线程,在在paint方法中使用两个输方法中使用两个输出字符串的语句出字符串的语句public void paint(Graphics g) if y1200 y2=0 else y2=y2+10; g.drawString(“hello, Java!”,20,y1,); g.drawString(“hello, Java!”,40,y2,);237

19、.4 多线程问题多线程问题-如何写多线程如何写多线程n方法二方法二:定义两个类定义两个类,运行各自的线程运行各自的线程,各自有自各自有自己的己的paint()方法方法.n注意注意: 两个小应用程序必须是两个小应用程序必须是panel类或者是类或者是canvas类类,将小应用的区域分成两块将小应用的区域分成两块,否则不能否则不能运行运行paint语句语句.247.4 多线程问题多线程问题-线程间的通信线程间的通信1. 线程间的通信可以用管道流线程间的通信可以用管道流,.创建管道流创建管道流:PipedInputStream pis=new PipedInputStream();PipedOutp

20、utStream pos=new PipedOutputStream(pis);或或:PipedOutputStream pos=new PipedOutputStream();PipedInputStream pis=new PipedInputStream(pos);线程线程1PipedOutputStream PipedInputStream输出流输出流outStream输入流输入流inStream线程线程2257.4 多线程问题多线程问题-线程间的通信线程间的通信n管道管道流不能直流不能直 接读写接读写PrintStream p = new PrintStream( pos );p.p

21、rintln(“hello”);DataInputStream d=new DataInputStream(pis);d.readLine();n2. 通过一个中间类来传递信息通过一个中间类来传递信息.线程线程2线程线程1中间类中间类mssm.write(s)s=m.read()write()read()printStream DataInputStream267.4 多线程问题多线程问题-线程间的通信线程间的通信n管道流可以连接两个线程间的通信管道流可以连接两个线程间的通信n下面的例子里有两个线程在运行下面的例子里有两个线程在运行,一个往外输出一个往外输出信息信息,一个读入信息一个读入信息.

22、n将一个写线程的输出通过管道流定义为读线程将一个写线程的输出通过管道流定义为读线程的输入的输入.outStream = new PipedOutputStream();inStream = new PipedInputStream(outStream);new Writer( outStream ).start();new Reader( inStream ).start(); 27n(threadPipethread.class-f3.bat)7.4 多线程问题多线程问题-线程间的通信线程间的通信主类主类Pipethread辅类辅类Writer线线程程类类辅类辅类Reader线线程程类类管管

23、道道流流将数据写将数据写到输出流到输出流从流中读数据从流中读数据输入流输入流作为参数传给作为参数传给WriterWriter( outStream )287.4 多线程问题多线程问题-线程间的通信线程间的通信n.public class Pipethread public static void main(String args) Pipethread thisPipe = new Pipethread(); thisPcess(); public void process() PipedInputStream inStream; PipedOutputStream outStr

24、eam; PrintStream printOut; try outStream = new PipedOutputStream(); inStream = new PipedInputStream(outStream); new Writer( outStream ).start(); new Reader( inStream ).start(); catch( IOException e ) 297.4 多线程问题多线程问题-线程间的通信线程间的通信class Reader extends Thread private PipedInputStream inStream;/从中读数据从中读

25、数据 public Reader(PipedInputStream i) inStream = i; public void run() String line; DataInputStream d; boolean reading = true; try d = new DataInputStream( inStream ); while( reading & d != null) tryline = d.readLine(); if( line != null ) System.out.println( ”Read: + line ); else reading = false; catc

26、h( IOException e) catch( IOException e ) System.exit(0); try Thread.sleep( 4000 ); catch( InterruptedException e )307.4 多线程问题多线程问题-线程间的通信线程间的通信n.class Writer extends Thread private PipedOutputStream outStream;/将数据输出将数据输出 private String messages = Monday, Tuesday , Wednsday, Thursday,Friday :, Saturd

27、ay:,Sunday :; public Writer(PipedOutputStream o) outStream = o; public void run() PrintStream p = new PrintStream( outStream ); for (int i = 0; i messages.length; i+) p.println(messages i ); p.flush(); System.out.println(WrIte: + messagesi ); p.close(); p = null; 317.5 多线程问题多线程问题-资源协调资源协调1. 数据的完整性数据

28、的完整性线程线程1线程线程2线程线程10资源资源取过来取过来加加1后送回去后送回去withdrwal()withdrwal()透支透支余额余额变量变量327.5 多线程问题多线程问题-资源协调资源协调n对共享对象的访问必须同步对共享对象的访问必须同步,叫做条件变量叫做条件变量.nJava语言允许通过监视器语言允许通过监视器(有的参考书称其为有的参考书称其为管程管程)使用条件变量实现线程同步使用条件变量实现线程同步.n监视器阻止两个线程同时访问同一个条件变量监视器阻止两个线程同时访问同一个条件变量.它的如同锁一样作用在数据上它的如同锁一样作用在数据上.n线程线程1进入进入withdrawal方法

29、时方法时,获得监视器获得监视器(加加锁锁);当线程当线程1的方法执行完毕返回时的方法执行完毕返回时,释放监视释放监视器器(开锁开锁),线程线程2的的withdrawal方能进入方能进入.withdrawal()线程线程1监视器监视器线程线程2337.5 多线程问题多线程问题-资源协调资源协调n用用synchronized来标识的区域或方法即为监视来标识的区域或方法即为监视器监视的部分。器监视的部分。n一个类或一个对象由一个监视器一个类或一个对象由一个监视器,如果一个程如果一个程序内有两个方法使用序内有两个方法使用synchronized标志标志,则他则他们在一个监视器管理之下们在一个监视器管理

30、之下.n一般情况下,只在方法的层次上使用关键区一般情况下,只在方法的层次上使用关键区readwrite监监视视器器线程线程1线程线程2347.5 多线程问题多线程问题-资源协调资源协调此处给出的例子演示两个线程在同步限制下工作的情况此处给出的例子演示两个线程在同步限制下工作的情况.class Account statics int balance=1000; /为什么用为什么用static? statics int expense=0; public synchronized void withdrawl(int amount) if (amountf4.bat377.5 多线程问题多线程问题

31、-资源协调资源协调writerreaderaaaabbbbbccccaaaaaaaaaaaaaaaaaaaaaaaabbbbbcccc ccccccccccccbbbbbcccc387.5 多线程问题多线程问题-资源协调资源协调nclass WaitNotifyDemo n public static void main(String args) n MessageBoard m = new MessageBoard();n Reader readfrom_m = new Reader(m);n Writer writeto_m=new Writer(m);n readfrom_m.start

32、(); n writeto_m.start();n n397.3 多线程问题多线程问题-资源协调资源协调class MessageBoard private String message; private boolean ready = false;(信号灯信号灯) public synchronized String read() while (ready = false) try wait(); catch (InterruptedException e) ready = false; notify(); /起始状态先写后读起始状态先写后读return message; public sy

33、nchronized void write(String s) while (ready = true) try wait(); catch (InterruptedException e) message = s; ready = true; notify(); 407.3 多线程问题多线程问题-资源协调资源协调class Reader extends Thread private MessageBoard mBoard; public Reader(MessageBoard m) mBoard = m; public void run() String s = ;boolean readi

34、ng = true;while( reading ) s = mBoard.read(); System.out.println(Reader read: + s); if( s.equals(logoff) ) reading = false; System.out.println(Finished: 10 seconds.);try sleep( 10000 ); catch (InterruptedException e) 417.3 多线程问题多线程问题-资源协调资源协调class Writer extends Thread private MessageBoard mBoard; p

35、rivate String messages = Monday :-,“.”,Sunday : -; public Writer(MessageBoard m) mBoard = m; public void run() for (int i = 0; i dir|sort|more 这里使用了两个管道(用|表示)把三个命令连在一起,第一个管道把dir命令的输出连接到sort命令的输入,第二个管道将sort命令的输出连到more命令的输入,从而实现生成目录清单,进行排序后,一页一页地显示。 nJava使用了管道技术,用PipedInputStream类和PipedOutputStream类实现

36、管道操作,这两个类必须同时使用 。 815.2.6其它输入输出流类(三)n管道技术在多线程系统中使用较多,它可以解决不同线程之间同步通讯的问题,从而保证大量数据交换顺利进行。n要实现多线程的同步通讯,必须把管道连接起来,这里有两种方法实现管道的连接:使用带参数的构造函数。使用不带参数的构造函数,再调用任何一个类的connect()方法,实现输入管道和输出管道的连接。82运行结果835.2.5加强输入输出流类 (五)3DataInputStream类和DataOutputStream类 n结合RandomAccessFile类就很容易理解这两个类,因为,RandomAccessFile类同时实现

37、了两个接口: dataInput接口和DataOutput接口 而DataInputStream类和DataOutputStream类分别实现了这两个接口。 DataInputStream类中读数据的方法和DataOutputStream类中写数据的方法,与RandomAccessFile类中的读写方法含义完全一致,在此不再赘述。 845.2.6其它输入输出流类(一)n本节将介绍的输入流类有: SequenceInputStream类 PipedInputStream类n输出流类有: PipedOutputStream类 1SequenceInputStream类 nSequenceInputStream类可以将两个或几个输入流不露痕迹地接合在一起,生成一个长长的接合流,在读入数据时,它忽略前面几个输入流的结束符EOF,直到最后一个流的结束符EOF时,才完成流的输入,其定义如下: 855.2.6其它输入输出流类(二)2管道输入输出流类 n管道是UNIX的发明,它

温馨提示

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

评论

0/150

提交评论