收藏 分享(赏)

交大JAVA讲义第11章Java线程.ppt

上传人:精品资料 文档编号:11332671 上传时间:2020-03-18 格式:PPT 页数:41 大小:288.50KB
下载 相关 举报
交大JAVA讲义第11章Java线程.ppt_第1页
第1页 / 共41页
交大JAVA讲义第11章Java线程.ppt_第2页
第2页 / 共41页
交大JAVA讲义第11章Java线程.ppt_第3页
第3页 / 共41页
交大JAVA讲义第11章Java线程.ppt_第4页
第4页 / 共41页
交大JAVA讲义第11章Java线程.ppt_第5页
第5页 / 共41页
点击查看更多>>
资源描述

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

2、在运行),5,11.1 线程基本概念,线程与进程的区别:1)多个进程的内部数据和状态都是完全独立的,而多线程是共享一块内存空间和一组系统资源,有可能互相影响.2)线程本身的数据通常只有寄存器数据,以及一个程序执行时使用的堆栈,所以线程的切换比进程切换的负担要小。,6,11.1 线程基本概念,对线程的综合支持是Java技术的一个重要特色.java内在支持多线程,它的所有类都是在多线程的思想下定义的。Java中的线程可以认为由三部分组成:虚拟CPU,代码和数据。1)虚拟CPU封装在java.lang.Thread类中。2)虚拟CPU执行的代码,传递给Thread的类3)虚拟CPU处理的数据,传递给

3、Thread的类 虽然Macintosh,Windows NT,Windows 9等操作系统支持多线程,但若要用C或C+编写多线程程序是十分困难的,因为它们对数据同步的支持不充分.,7,11.2 线程的使用,11.2.1 线程体线程的所有活动都是通过线程的run( )方法实现的,一个线程建立并初始化以后,运行时就自动调用run( )方法。线程执行的起点从run( )方法开始,就像应用程序从main( )方法一样。 run方法是运行线程的主体,启动线程时,由java直接调用 public void run(),8,11.2 线程的使用,11.2.2线程体的构造 1.直接继承线程类Threadpu

4、blic class mythread extends Thread方法中用类Thread产生线程的对象 Thread newthread; 2,通过接口构造线程体通过建立一个实现Runnable接口的对象,并以它作为目标对象构造线程体。,9,11.2 线程的使用,11.2.3线程的状态在线程的各生命周期中,它总出于某种状态中,线程的状态表示了线程正在进行的活动以及在这段时间内线程能完成的任务1)创建状态,当一个线程处于创建状态时,它仅仅是一个空的线程对象,系统不为它分配资源。2)可运行状态,线程处于该状态时,系统为这个线程分配了所需资源。3)运行中状态,当处于此状态时,系统为这个线程分配了所

5、需资源,该线程占有CPU。4)不可运行状态,也称为阻塞状态,由于某种原因,系统不能执行线程的状态。5)死亡状态,线程执行结束,可以是自然撤销或被停止。自然撤销是从线程中正常退出,被停止是应用程序停止运行。当一个线程执行完所有语句后就自动终止,调用线程的stop()方法,也可以强制终止线程。,10,11.2 线程的使用,11. 2.3线程的状态,11,11.2.3 线程的状态,线程状态及状态转换示意图,12,11.2 线程的使用,11.2.4 线程的调度 线程的优先权 某一时刻只有一个线程在执行,调度策略为固定优先级调度. newthread.setPriority(Thread.MIN_PRI

6、ORITY) 级别有:MIN-PRIORITYNORM_PRIORITYMAX-PRIORITY自私的线程:有很高的优先权的线程,不主动睡眠或让出处理器控制权.,13,11.2 线程的使用,11.2.5线程的控制 1 创建并启动线程newthread=new Thread(this);newthread.start();/启动线程 2 不可运行状态 停止线程,由小应用程序的stop调用线程的stop newthread.stop() 调用了sleep方法的作用,暂停线程的执行,让其它线程得到机会,sleep要丢出异常,必须抓住.Trysleep(100)catch(InterruptedExc

7、eption e) 为了等一个条件变量,线程调用了wait()方法,如果要停止等待,需要调用notify() or notifyall()方法。 输入输出流中发生了线程阻塞3 停止线程线程停止后即为死亡,分为自然撤销和被停止,14,11.2 线程的使用,11.2.6线程调度的方法sleep():当前线程睡眠若干毫秒,由运行状态进入不可运行状态,睡眠过后再进入可运行状态。yield():引起当前线程暂停执行,以允许其他线程执行。线程处于可运行状态。isAlive() :判断线程目前是否正在执行状态中if(newthread.isAlive() newthread.stop();resume():

8、要求被暂停的线程继续执行suspend():暂停线程的执行join():等待调用该方法线程执行完毕thatThread.join();被等待的那个线程不结束,当前线程就一直等待.yield:将执行的权力交给其它线程,自己到队列的最后等待. Wait():用于实现线程间通信的同步控制方法。具体见教材264页。,15,11.2 线程的使用,11.2.7有关线程的其他概念 什么是daemon(守护)?在客户/服务器模式下,服务器的作用是等待用户发来请求,并按请求完成客户的工作守护线程是为其它线程提供服务的线程守护线程一般应该是一个独立的线程,它的run()方法是一个无限循环.守护线程与其它线程的区别

9、是,如果守护线程是唯一运行着的线程,程序会自动退出,16,11.2 线程的使用,11.2.7有关线程的其他概念,客户端,服务器端,request,daemon,17,11.3同步与共享,1. 数据的完整性,18,11.3同步与共享,对共享对象的访问必须同步,保证任何时刻只能有一个线程访问该对象. Java语言允许通过监视器(Monitor Model)模型实现线程同步. 监视器阻止两个线程同时访问同一个对象,它的如同锁一样作用在数据上. 线程1进入withdrawal方法时,获得监视器(加锁);当线程1的方法执行完毕返回时,释放监视器(开锁),线程2的withdrawal方能进入.,19,11

10、.3同步与共享,用synchronized来标识的区域或方法即为监视器监视的部分。 一个类或一个对象有一个监视器,如果一个程序内有两个方法使用synchronized标志,则他们在一个监视器管理之下.,20,11.3同步与共享,例子:两个线程在同步限制下工作的情况. class Account statics int balance=1000; statics int expense=0;public synchronized void withdrawl(int amount) if (amount=balance) balance-=amount;expense+=amount;else

11、System.out.println(“bounced: “+amount); ,21,11.3同步与共享,2. 等待同步数据,可能出现的问题: 生产者比消费者快时,消费者会漏掉一些数据没有取到 消费者比生产者快时,消费者取相同的数据. notify()和wait ()方法用来协调读取的关系. notify()和wait ()都只能从同步方法中的调用.,22,11.3同步与共享,Notify()的作用是唤醒正在等待同一个监视器的线程. wait的作用是让当前线程等待 read()方法在读信息之前先等待,直到信息可读,读完后通知要写的线程. write()方法在写信息之前先等待,直到信息被取走,

12、写完后通知要读的进程. 例,DemoWait.class,23,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(); ,24,11.3同步与共享,class MessageBoard private String message; pri

13、vate 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 = true) try wait(); catch (InterruptedException e) message = s; re

14、ady = true;notify(); ,25,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();System.out.println(“Reader read: “ + s);if( s.equals(“logoff“) ) reading = fa

15、lse; System.out.println(“Finished: 10 seconds.“);try sleep( 10000 ); catch (InterruptedException e) ,26,11.3同步与共享,class Writer extends Thread private MessageBoard mBoard;private String messages = “Monday :-“,“”,“Sunday : -“;public Writer(MessageBoard m) mBoard = m; public void run() for (int i = 0;

16、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“); ,27,11.3同步与共享,3. 死锁问题如果你持有一个锁并试图获取另一个锁时,就有死锁的危险. 解决死锁问题的方法:给条件变量施加排序,28,11.4-线程间的通信,1. 线程间的通信可以用管道流,.创建管道流: Pi

17、pedInputStream pis=new PipedInputStream(); PipedOutputStream pos=new PipedOutputStream(pis); 或: PipedOutputStream pos=new PipedOutputStream(); PipedInputStream pis=new PipedInputStream(pos);,29,11.4-线程间的通信,管道流不能直 接读写PrintStream p = new PrintStream( pos ); p.println(“hello”); DataInputStream d=new Da

18、taInputStream(pis); d.readLine(); 2. 通过一个中间类来传递信息.,30,11.4-线程间的通信,管道流可以连接两个线程间的通信 下面的例子里有两个线程在运行,一个往外输出信息,一个读入信息. 将一个写线程的输出通过管道流定义为读线程的输入. outStream = new PipedOutputStream(); inStream = new PipedInputStream(outStream); new Writer( outStream ).start(); new Reader( inStream ).start();,31,(threadPipet

19、hread.class),11.4-线程间的通信,主类Pipethread,辅类Writer 线 程 类,辅类 Reader 线 程 类,管 道 流,将数据写 到输出流,从流中读数据,输入流,作为参数传给Writer Writer( outStream ),32,11.4-线程间的通信,public class Pipethread public static void main(String args) Pipethread thisPipe = new Pipethread(); thisPipe.process(); public void process() PipedInputStr

20、eam inStream; PipedOutputStream outStream;PrintStream printOut;try outStream = new PipedOutputStream();inStream = new PipedInputStream(outStream);new Writer( outStream ).start();new Reader( inStream ).start(); catch( IOException e ) ,33,11.4-线程间的通信,class Reader extends Thread private PipedInputStrea

21、m inStream;/从中读数据public Reader(PipedInputStream i) inStream = i; public void run() String line; DataInputStream d;boolean reading = true;try d = new DataInputStream( inStream );while( reading catch( InterruptedException e ),34,11.4-线程间的通信,class Writer extends Thread private PipedOutputStream outStre

22、am;/将数据输出private String messages = “Monday“, “Tuesday “,“Wednsday“, “Thursday“,“Friday :“,“Saturday:“,“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();Sy

23、stem.out.println(“WrIte:“ + messagesi ); p.close(); p = null; ,35,11.5 线程的挂起与唤醒,暂停线程的执行等待条件满足再执行.例如:小应用程序第一次开始时,线程被启动浏览器改变页面时,小应用程序的stop()方法被调用,线程被挂起.浏览器回到原来的页面时,线程被唤醒. 下面的例子显示线程的挂起和唤醒,36,11.5 线程的挂起与唤醒,public void start() if (mythread=null)mythread=new Thread(); mythread.start();else mythread.resume

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

25、AX_PRIORITY),38,11.6 多线程问题-执行的顺序,/多个进程运行时执行顺序是交叉的 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(“thread “+threadNum+ “bye.“);,39,11.6 多线程问题-如何写多线程,1.分别定义不同的线程类,在各自的run方法中定义线程的工作cl

26、ass 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();t1.start(); t2.start(); ,40,11.7 小结,1. 实现线程有两种方法: 实现Ruannable接口 继承Thread类 2. 在小应用中通常在start中创建线程 3.当新线程被启动时,java调用该线程的run方 法,它是Thread的核心. 4. 线程由四个状态:新生,运行,暂停,死亡 5. 线程间的通信方式由三种:完全共享数据,通过监视器,通过join.,41,11.7 小结,6. 两个或多个线程竞争资源时,需要用同步的方法协调资源. 7. 多个线程执行时,要用到同步方法,即使用 synchronized关键字设定同步区 8. wait和notify起协调作用 9. 守护进程的特点是当程序中只剩它自己时,会自动中止.,

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

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报