第11章 多线程.ppt

上传人:孙刚 文档编号:388358 上传时间:2018-10-12 格式:PPT 页数:46 大小:147.50KB
下载 相关 举报
第11章 多线程.ppt_第1页
第1页 / 共46页
第11章 多线程.ppt_第2页
第2页 / 共46页
第11章 多线程.ppt_第3页
第3页 / 共46页
第11章 多线程.ppt_第4页
第4页 / 共46页
第11章 多线程.ppt_第5页
第5页 / 共46页
亲,该文档总共46页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

1、第11章 多线程,2,第11章 多线程,11.1 多线程基本概念 11.2 创建线程的方式 11.3 线程的挂起与唤醒 11.4 多线程问题 11.5 小结,3,11.1 多线程基本概念,文件,输入输出装置,各种系统资源,数据区段,程序区段,只有一个地方在执行,文件,输入输出装置,各种系统资源,程序区段,同时有数个地方在执行,传统的进程,多线程的任务,4,11.1 多线程基本概念,多线程的优势: 减轻编写交互频繁、涉及面多的程序的困难. 程序的吞吐量会得到改善. 由多个处理器的系统,可以并发运行不同的线程.(否则,任何时刻只有一个线程在运行),5,11.1 多线程基本概念,线程与进程的区别:

2、多个进程的内部数据和状态都是完全独立的,而多线程是共享一块内存空间和一组系统资源,有可能互相影响. 线程本身的数据通常只有寄存器数据,以及一个程序执行时使用的堆栈,所以线程的切换比进程切换的负担要小。,6,11.1 多线程基本概念,对线程的综合支持是Java技术的一个重要特色.它提供了thread类、监视器和条件变量的技术. 虽然Macintosh,Windows NT,Windows 9等操作系统支持多线程,但若要用C或C+编写多线程程序是十分困难的,因为它们对数据同步的支持不充分.,7,11.2 创建线程的方式,1. public class mythread extends Applet

3、 implements Runnable(小应用或已经是某个类的子类时) 2. 继承类Threadpublic class mythread extends Thread 3. 上述两种方法中都可用类Thread产生线程的对象 Thread newthread; 4. 创建并启动线程newthread=new Thread(this);newthread.start();,8,11.2 创建线程的方式,5. run方法是运行线程的主体,启动线程时,由java直接调用 public void run() 6.停止线程,由小应用程序的stop调用线程的stop newthread.stop() 1

4、1 sleep方法的作用,暂停线程的执行,让其它线程得到机会,sleep要丢出异常,必须抓住. Trysleep(100)catch(InterruptedException e) 例:小应用程序中不用Runnable接口仍然可以使用线程(不调用主类的方法和调用主类的方法),9,import java.applet.*; public class thread extends Applet mythread t1=new mythread();public init() t1.start(); class mythread extends Thread public void run() fo

5、r (int i=0;i4;i+) System.out.println( “”+i); trysleep(400); catch(InteruptedException e) ,11.2 创建线程的方式,10,11.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

6、 a;C(mainclass b) a=b; public void run() while(true) a.repaint();trysleep(400); catch(InterruptedException e) ,11,11.2 创建线程的方式,8.其它常用的方法isAlive :判断线程目前是否正在执行状态中if(newthread.isAlive() newthread.stop();resume:要求被暂停得线程继续执行suspend:暂停线程的执行join:等待线程执行完毕thatThread.join();被等待的那个线程不结束,当前线程就一直等待.yield:将执行的权力交

7、给其它线程,自己到队列的最后等待.,12,11.2 创建线程的方式,9.线程的优先权 某一时刻只有一个线程在执行,调度策略为固定优先级调度. newthread.setPriority(Thread.MIN_PRIORITY) 级别有:MIN-PRIORITYNOM_PRIORITYMAX-PRIORITY 10. 自私的线程:有很高的优先权的线程,不主动睡眠或让出处理器控制权.,13,11.2 创建线程的方式,11. 线程的状态,14,11.2 创建线程的方式,当一个线程执行完所有语句后就自动终止,调用线程的stop()方法,也可以强制终止线程。 如果希望线程正常终止,可采用标记来使线程中的

8、run()方法退出。,15,11.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; ,16,11.2 创建线程的方式,public class ControlThread private Runnable r=new Xyz();private Thread t=new T

9、hread(r);public void startThread() t.start(); publi void stopThread() r.stopRunning(); ,17,11.3 线程的挂起与唤醒,暂停线程的执行等待条件满足再执行. 下面的例子显示线程的挂起和唤醒 小应用程序第一次开始时,线程被启动 浏览器改变页面时,小应用程序的stop()方法被调用,线程被挂起. 浏览器回到原来的页面时,线程被唤醒.,18,11.3 线程的挂起与唤醒,public void start() if (mythread=null)mythread=new Thread(); mythread.sta

10、rt();else mythread.resume(); public void run() while(true) trysleep(100);catch(InterruptedException e) public void stop() mythread.suspend(); .,19,11.4 多线程问题-执行的顺序,多个线程运行时,调度策略为固定优先级调度.级别相同时,由操作系统按时间片来分配 下面给出的例子中,共运行三个线程,它们做同样的事, 每次打印循环次数和自己的序列号,运行结果表明,它们并不是连续运行的. 在上例中如果给某个线程赋予较高的优先权,则发现这个进程垄断控制权thr

11、ead.setPriority(Thread.MAX_PRIORITY) threadmultithread.class-f1.bat threadPriority.class-f2.bat,20,11.3 多线程问题,/多个进程运行时执行顺序是交叉的 class multithread extends Thread int threadNum;public static void main(String args) multithread array=new multithread3;for (int i=0;i +MySerialNum);System.out.println(“threa

12、d “+threadNum+ “bye.“);,21,11.4 多线程问题-如何写多线程,1.分别定义不同的线程类,在各自的run方法中定义线程的工作class mythread1 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();

13、t1.start(); t2.start(); ,22,11.4 多线程问题-如何写多线程,练习:将窗口分为上下两个区,分别运行两个线程,一个在上面的区域中显示由右向左游动的字符串,另一个在下面的区域从左向右游动的字符串. 方法一: 一个线程,在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,); ,23,11.4 多线程问题-如何写多线程,方法二

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

15、=new PipedInputStream(pos);,25,11.4 多线程问题-线程间的通信,管道流不能直 接读写PrintStream p = new PrintStream( pos ); p.println(“hello”); DataInputStream d=new DataInputStream(pis); d.readLine(); 2. 通过一个中间类来传递信息.,26,11.4 多线程问题-线程间的通信,管道流可以连接两个线程间的通信 下面的例子里有两个线程在运行,一个往外输出信息,一个读入信息. 将一个写线程的输出通过管道流定义为读线程的输入. outStream =

16、new PipedOutputStream(); inStream = new PipedInputStream(outStream); new Writer( outStream ).start(); new Reader( inStream ).start();,27,(threadPipethread.class-f3.bat),11.4 多线程问题-线程间的通信,主类Pipethread,辅类Writer 线 程 类,辅类 Reader 线 程 类,管 道 流,将数据写 到输出流,从流中读数据,输入流,作为参数传给Writer Writer( outStream ),28,11.4 多

17、线程问题-线程间的通信,.,public class Pipethread public static void main(String args) Pipethread thisPipe = new Pipethread(); thisPipe.process(); public void process() PipedInputStream inStream; PipedOutputStream outStream;PrintStream printOut;try outStream = new PipedOutputStream();inStream = new PipedInputSt

18、ream(outStream);new Writer( outStream ).start();new Reader( inStream ).start(); catch( IOException e ) ,29,11.4 多线程问题-线程间的通信,class Reader extends Thread private PipedInputStream inStream;/从中读数据public Reader(PipedInputStream i) inStream = i; public void run() String line; DataInputStream d;boolean re

19、ading = true;try d = new DataInputStream( inStream );while( reading catch( InterruptedException e ),30,11.4 多线程问题-线程间的通信,.,class Writer extends Thread private PipedOutputStream outStream;/将数据输出private String messages = “Monday“, “Tuesday “,“Wednsday“, “Thursday“,“Friday :“,“Saturday:“,“Sunday :“;pub

20、lic 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; ,31,11.3 多线程问题-资源协调,1. 数据的完整性,32,11.3 多线程问题-资源协调,对共享对象

21、的访问必须同步,叫做条件变量. Java语言允许通过监视器(有的参考书称其为管程)使用条件变量实现线程同步. 监视器阻止两个线程同时访问同一个条件变量.它的如同锁一样作用在数据上. 线程1进入withdrawal方法时,获得监视器(加锁);当线程1的方法执行完毕返回时,释放监视器(开锁),线程2的withdrawal方能进入.,33,11.3 多线程问题-资源协调,用synchronized来标识的区域或方法即为监视器监视的部分。 一个类或一个对象由一个监视器,如果一个程序内有两个方法使用synchronized标志,则他们在一个监视器管理之下.一般情况下,只在方法的层次上使用关键区,34,1

22、1.3 多线程问题-资源协调,此处给出的例子演示两个线程在同步限制下工作的情况. class Account statics int balance=1000; /为什么用static?statics int expense=0;public synchronized void withdrawl(int amount) if (amount=balance) balance-=amount;expense+=amount;else System.out.println(“bounced: “+amount); ,35,11.3 多线程问题-资源协调,2. 等待同步数据,可能出现的问题: 生产

23、者比消费者快时,消费者会漏掉一些数据没有取到 消费者比生产者快时,消费者取相同的数据. notify()和wait ()方法用来协调读取的关系. notify()和wait ()都只能从同步方法中的调用.,36,11.3 多线程问题-资源协调,notify的作用是唤醒正在等待同一个监视器的线程. wait的作用是让当前线程等待 信息版例子 read()方法在读信息之前先等待,直到信息可读,读完后通知要写的线程. write()方法在写信息之前先等待,直到信息被取走,写完后通知要读的进程. DemoWait.class-f4.bat,37,11.3 多线程问题-资源协调,writer,reade

24、r,aaaa,bbbbb,cccc,aaaa,aaaa,aaaa,aaaa,aaaa,aaaa,bbbbb,cccc,cccc,cccc,cccc,bbbbb,cccc,38,11.3 多线程问题-资源协调,class WaitNotifyDemo public static void main(String args) MessageBoard m = new MessageBoard();Reader readfrom_m = new Reader(m);Writer writeto_m=new Writer(m);readfrom_m.start(); writeto_m.start()

25、; ,39,11.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 synchronized void write(String s) while (ready

26、 = true) try wait(); catch (InterruptedException e) message = s; ready = true; notify(); ,40,11.3 多线程问题-资源协调,class Reader extends Thread private MessageBoard mBoard;public Reader(MessageBoard m) mBoard = m; public void run() String s = “ “;boolean reading = true;while( reading )s = mBoard.read();Sys

27、tem.out.println(“Reader read: “ + s);if( s.equals(“logoff“) ) reading = false; System.out.println(“Finished: 10 seconds.“);try sleep( 10000 ); catch (InterruptedException e) ,41,11.3 多线程问题-资源协调,class Writer extends Thread private MessageBoard mBoard;private String messages = “Monday :-“,“”,“Sunday :

28、 -“;public Writer(MessageBoard m) mBoard = m; public void run() for (int i = 0; i messages.length; i+) mBoard.write(messages i );System.out.println(“Writer wrote:“ + messagesi );try sleep(int)(Math.random() * 100); catch (InterruptedException e) mBoard.write(“logoff“); ,42,11.3 多线程问题-资源协调,多线成问题-资源的协

29、调和锁定 1. 死锁问题如果你的持有一个锁并试图获取另一个锁时,就有死锁的危险. 解决死锁问题的方法:给条件变量施加排序,43,11.3 多线程问题-daemon线程,什么是daemon(守护)? 在客户/服务器模式下,服务器的作用是等待用户发来请求,并按请求完成客户的工作守护线程是为其它线程提供服务的线程 守护线程一般应该是一个独立的线程,它的run()方法是一个无限循环. 守护线程与其它线程的区别是,如果守护线程是唯一运行着的线程,程序会自动退出,客户端,服务器端,request,daemon,44,11.4 小结,1. 实现线程有两种方法: 实现Ruannable接口 继承Thread类

30、 2. 在小应用中通常在start中创建线程 3.当新线程被启动时,java调用该线程的run方 法,它是Thread的核心. 4. 线程由四个状态:新生,运行,暂停,死亡 5. 线程间的通信方式由三种:完全共享数据,通过监视器,通过join.,45,11.4 小结,6. 两个或多个线程竞争资源时,需要用同步的方法协调资源. 11. 多个线程执行时,要用到同步方法,即使用 synchronized的关键字设定同步区 8. wait和notify起协调作用 9. 守护进程的特点是当程序中制胜它自己时,会自动中止.,46,作业,创建两个线程的实例,分别将一个数组从小大大和从达到小排列.输出结果.,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 教学课件 > 大学教育

copyright@ 2008-2019 麦多课文库(www.mydoc123.com)网站版权所有
备案/许可证编号:苏ICP备17064731号-1