版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第九章多线程技术第九章多线程技术9.1多线程基本概念9.2创建线程的方式9.3改变线程状态的方法9.4多线程问题9.1多线程基本概念线程概念线程与进程的区别线程的优越性线程的状态及转换线程概念并发多任务的实现采用的是在操作系统(OS)级运行多个进程。由于各个进程拥有自己独立的运行环境,进程间的耦合关系差,并发粒度过于粗糙,并发实现也不太容易。为提高计算机的并行效率提出了线程概念。如果把进程所占资源与进程中的运行代码相分离,那么在一个地址空间中便可运行多个指令流,由此产生线程概念。一般说来,所谓线程,指程序中的一个单一的顺序控制流。
线程与进程的区别图1和图2分别示意了把一个任务按2个并发进程和2个并发线程分解后的情况。各个进程是在自己独有的地址空间内执行,不但寄存器和堆栈是独有的,动态数据堆、静态数据区和程序代码也相互独立。各线程为保持自己的控制流而独有寄存器和堆栈,但由于两线程从属于同一进程,它们共享同一地址空间,所以动态堆、静态数据区及程序代码为各线程共享,所以线程的切换比进程切换的负担要小。进程作为独立的实体,它为线程提供运行的资源并构成静态环境。线程是处理机调度的基本单位。线程的优越性快速的关联切换
由于操作系统级的进程独占自己的虚地址空间,调度进程时,系统必须交换地址空间,因而进程切换时间长。在同一程序内的多个线程共享同一地址空间,因而能使线程快速切换。系统额外开销小
对多个进程的管理(创建、调度等)有比较大的系统开销。在需要动态创建新进程的应用中,这种开销比较显著。而对线程的管理虽然也会有系统开销,但比进程的小得多。通信很容易实现
为了实现协作,进程或线程之间需要进行数据交换。对于自动共享同一地址空间的各线程来说,所有的全局数据都可以访问,因而不需要什么特殊手段就能自动实现数据共享。而进程之间的通信则要复杂得多。线程个数比进程个数多得多
许多多任务操作系统限制用户进程总数。在多线程系统中,虽存在线程总数限额,但个数多得多(OS/2支持4096个线程)。线程的状态及转换新建(New):代表线程的对象已经被初始化,但尚未运行run方法。就绪(Runnable):线程正在运行run方法,但这只说明线程目前处于的状态。如果系统没有能力抽出CPU执行时间给线程,线程就“不执行”,这里的“不执行”不代表“阻塞”或“死亡”。运行(Running):线程获得了CPU资源正在执行任务,将一直运行到结束,除非此时它自动放弃资源或有更加高优先级的线程进入。阻塞(NotRunnable):线程是可以执行的,但由于某些因素的阻碍处于停滞状态,系统排程器略过了应给线程的CPU执行时间。死亡(Dead):线程的正式结束方式,run方法执行完毕并返回。线程的状态及转换newThread()NewThreadRunnablestart()NotRunnablestop()stop()Deadyield()stop()orrun()exit..suspend()sleep()wait()resume().9.2创建线程的方式为了创建一个新的线程,必须指明这个线程所要执行的代码,Java是通过类做到这一点的。作为一个面向对象的程序设计语言,Java提供了java.lang.Thread类来进行多线程编程。Java中实现线程主要有两种方法。继承Thread类,覆盖方法run()实现Runnable接口继承Thread类Thread类最重要的方法是run()方法,它为Thread类的start()方法所调用,并提供线程所要执行的代码。为了指定自己新的代码,只需要覆盖它即可,即在创建的Thread类的子类中重写run(),加入线程所要执行的代码。该方法的步骤是:从Thread类派生一个类,覆盖Thread类中的run方法,然后创建该子类的对象,再调用start方法启动本线程。importjava.applet.*;publicclassthreadextendsApplet{mythreadt1=newmythread();publicinit(){t1.start();}classmythreadextendsThread{publicvoidrun(){for(inti=0;i<4;i++)System.out.println(“”+i);{try{sleep(400);}catch(InteruptedExceptione){}}}实现Runnable接口Runnable接口只有一个方法run(),可以通过声明自己的类实现Runnable接口并提供这一方法,并将线程代码写入其中,就完成了这一部分的任务。但是Runnable接口并没有任何对线程的支持,还必须创建Thread类的实例,这一点通过Thread类的构造方法publicThread(Runnabletarget)来实现。publicclassControlThread{privateRunnabler=newXyz();privateThreadt=newThread(r);
publicvoidstartThread(){t.start();}
publivoidstopThread(){r.stopRunning();}}publicclassXyzimplementsRunnable{privatebooleantimeToQuit=false;
publicvoidrun()
{while(!timeToQuit){…..}}publicvoidstopRunning(){timeToQuit=true;}}9.3改变线程状态的方法start():
启动线程run():
运行线程的主体,启动线程时,由java直接调用stop():
停止线程sleep():
暂停线程的执行,让其它线程得到机会,sleep要丢出异常,必须抓住isAlive():判断线程目前是否正在执行状态中resume():要求被暂停得线程继续执行suspend():暂停线程的执行join():等待线程执行完毕yield():将执行的权力交给其它线程,自己到队列的最后等待9.4多线程问题执行的顺序如何写多线程线程间的通信资源协调daemon线程执行的顺序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+">"+threadNum);System.out.println("thread"+threadNum+"bye.");}}第一次第二次执行的顺序多个线程运行时,调度策略为固定优先级调度.级别相同时,由操作系统按时间片来分配。上面面给出的例子中,共运行三个线程,它们做同样的事,每次打印循环次数和自己的序列号,由结果可以看出某一时刻只有一个线程在执行,多线程的执行顺序是交错的、不连续的。Java中对于线程的优先级可以进行如下设置:级别:MIN-PRIORITYNOM_PRIORITYMAX-PRIORITY执行的顺序classmultithreadextendsThread{intthreadNum;publicstaticvoidmain(Stringargs[]){multithreadarray[]=newmultithread[3];for(inti=0;i<3;i++)array[i]=newmultithread(i);array[1].setPriority(Thread.MAX_PRIORITY);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+">"+threadNum);System.out.println("thread"+threadNum+"bye.");}}第一次第二次如何写多线程1.分别定义不同的线程类,在各自的run方法中定义线程的工作
classmythread1extendsThread{publicvoidrun{….}}classmythread2extendsThread{publicvoidrun{….}}2.在主类中实例化各线程类,并启动线程.publicclassdemoextendsApplet{publicvoidinit(){mythreadt1=newmythread1();mythreadt2=newmythread2();t1.start();t2.start();}}线程间的通信管道流线程1PipedOutputStreamPipedInputStream输出流outStream输入流inStream线程2线程2线程1中间类mssm.write(s)s=m.read()write()read()中间类资源协调数据的完整性等待同步数据死锁问题数据的完整性银行卡副卡存折银行取过来减1000后送回去getmoney()getmoney()透支存款额存款额23数据的完整性getmoney()线程1监视器线程2线程1进入withdrawal方法时,获得监视器(加锁);当线程1的方法执行完毕返回时,释放监视器(开锁),线程2的withdrawal方能进入.对共享对象的访问必须同步,叫做条件变量.Java语言允许通过监视器(有的参考书称其为管程)使用条件变量实现线程同步.监视器阻止两个线程同时访问同一个条件变量.它的如同锁一样作用在数据上.24数据的完整性用synchronized来标识的区域或方法即为监视器监视的部分,称为关键区。如果一个程序内有两个方法使用synchronized标志,则他们在一个监视器管理之下.一般情况下,只在方法的层次上使用关键区readwrite监视器线程1线程2classAccount{staticsintstore=10000;//为什么用static?staticsintexpense=0;publicsynchronizedvoidgetmoney(intamount){if(amount<=store){store-=amount;expense+=amount;}else{System.out.println(“bounced:“+amount);}}等待同步数据生产者消费者..共享对象writeread可能出现的问题:生产者比消费者快时,消费者会漏掉一些数据没有取到消费者比生产者快时,消费者取相同的数据.notify()和wait()方法用来协调读取的关系.notify()和wait()都只能从同步方法中的调用.notify的作用是唤醒正在等待同一个监视器的线程.wait的作用是让当前线程等待classMessageBoard{ privateStringmessage; privatebooleanready=false;//(信号灯) publicsynchronizedStringread() { while(ready==false) { try{wait();} catch(InterruptedExceptione){} } ready=false; notify();//起始状态先写后读
returnmessage; } publicsynchronizedvoidwrite(Strings) { while(ready==true) { try{wait();} catch(InterruptedExceptione){} } message=s;ready=true;notify(); }}classReaderextendsThread{ privateMessageBoardmBoard; publicReader(MessageBoardm) {mBoard=m;} publicvoidrun(){ Strings=""; booleanreading=true; while(reading) { s=mBoard.read(); System.out.println("Readerread:"+s); if(s.equals("logoff"))reading=false;} System.out.println("Finished:10seconds..."); try{sleep(10000);} catch(InterruptedExceptione){} }}classWriterextendsThread{ privateMessageBoardmBoard; privateStringmessages[]={“1”,“.2”,“3”,”4”,”5”}; publicWriter(MessageBoardm) {mBoard=m;} publicvoidrun(){ for(inti=0;i<messages.length;i++) { mBoard.write(messages[i]); System.out.println("Writerwrote:"+messages[i]); try{ sleep((int)(Math.random()*100)); }catch(InterruptedExceptione){}} mBoard.write("logoff");}}}publicclassWaitNotifyDemo{publicstaticvoidmain(String[]args) { MessageBoardm=newMessageBoard(); Readerreadfrom_m=newReader(m); Writerwriteto_m=newWriter(m);
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026榆林市米脂冀东水泥有限公司招聘(8人)笔试模拟试题及答案解析
- 叙永县2026年公开考试选调事业单位工作人员(38人)考试参考题库及答案解析
- 化学专业毕业论文开题答辩
- 2026天津南开大学部分科研助理岗位招聘考试备考题库及答案解析
- 2026年问题隐患和制度措施“两个清单”
- 人工智能辅助下的英语口语迁移能力培养路径探究教学研究课题报告
- 2026年智能物流标准化行业创新报告
- 2026年网络安全工程师(数据脱敏)专项模拟卷
- 2026年舞台美术高级设计师答辩试题
- 2026年物流数据分析方案
- 广州恒运企业集团股份有限公司招聘笔试题库2026
- 机械加工业安全作业行为规范培训
- 2026年春人教版(新教材)初中信息科技八年级全一册第二学期教学计划及进度表(第4-6单元)
- 2026年中国铁路总公司面试常见问题解析
- 2025中国建筑集团有限公司所属单位招聘笔试试题附答案解析
- 23-华为的组织建设(6版)
- 2025年-2026年钢轨探伤工(高级)技能理论考试题库(附答案)
- 果茶店创业计划书
- 隐匿阴茎的诊治2025
- 2025年考研英语二真题及答案解析(完整版)
- 项目经理施工现场安全管理要点
评论
0/150
提交评论