《Java多线程机制》PPT课件.ppt

上传人:tia****nde 文档编号:11498988 上传时间:2020-04-26 格式:PPT 页数:20 大小:83.50KB
返回 下载 相关 举报
《Java多线程机制》PPT课件.ppt_第1页
第1页 / 共20页
《Java多线程机制》PPT课件.ppt_第2页
第2页 / 共20页
《Java多线程机制》PPT课件.ppt_第3页
第3页 / 共20页
点击查看更多>>
资源描述
第13章Java多线程机制,本章要点:进程与线程线程的状态多线程的实现方法通过继承Thread类实现多线程通过Runnable接口实现多线程线程的调度线程的同步实现,13.1Java中的线程,计算机的发展日新月异,个人计算机上的操作系统也纷纷采用多任务和分时设计,将早期只有大型计算机才具有的系统特性带到了个人计算机系统中。一般可以在同一时间内执行多个程序的操作系统都有进程的概念。一个进程就是一个执行中的程序,而每一个进程都有自己独立的一块内存空间、一组系统资源。在进程概念中,每一个进程的内部数据和状态都是完全独立的。Java程序通过流控制来执行程序流,程序中单个顺序的流控制称为线程,多线程则指的是在单个程序中可以同时运行多个不同的线程,执行不同的任务。多线程意味着一个程序的多行语句可以看上去几乎在同一时间内同时运行。,13.1.1进程与线程进程是程序的一次动态执行过程,它对应了从代码加载、执行至执行完毕的一个完整过程,这个过程也是进程本身从产生、发展至消亡的过程。如果把公司一天的工作比作一个进程,那么早上公司开门上班是进程的开始,晚上下班关门是进程的结束。线程是比进程更小的执行单位。一个进程在其执行过程中,可以产生多个线程,形成多条执行线索,每条线索,即每个线程也有它自身的产生、存在和消亡的过程,也是一个动态的概念。就像公司一天的工作开始后,可以有多个不同的“线程”进行运作,如财务部门、开发部门、销售部门等。我们知道,每个进程都有一段专用的内存区域,与此不同的是,线程间可以共享相同的内存单元(包括代码与数据),并利用这些共享单元来实现数据交换、实时通信与必要的同步操作。比如在公司一天的工作开始后,财务部门、开发部门和销售部门这3个线程可以共享公司的内部网络资源,财务部门、销售部门可以共享公司的账目数据等。多线程的程序能更好地表达和解决现实世界的具体问题,是计算机应用开发和程序设计的一个必然发展趋势。,13.1.2线程的状态一个线程在任何时候都处于某种线程状态。线程的几个主要状态有创建、运行、中断和死亡4种状态。1.创建(NewThread)Java的线程是通过java.lang.Thread类来实现的。当我们生成一个Thread类的对象之后,一个新的线程就产生了。执行下列语句时,线程就处于创建状态:ThreadmyThread=newMyThreadClass();当一个线程处于创建状态时,它仅仅是一个空的线程对象,系统不为它分配资源。,2.运行(Runnable)线程创建之后就具备了运行的条件,一旦轮到它来享用CPU资源时,就可以脱离创建它的主线程独立开始自己的生命周期了。执行下列语句时,线程就处于运行状态:ThreadmyThread=newMyThreadClass();myThread.start();当一个线程处于可运行状态时,系统为这个线程分配了它所需的系统资源,安排其运行并调用线程运行方法,这样就使得该线程处于可运行(Runnable)状态。需要注意的是这一状态并不是运行中状态(Running),因为线程也许实际上并未真正运行。由于很多计算机都是单处理器的,所以要在同一时刻运行所有的处于可运行状态的线程是不可能的,Java的运行系统必须实现调度来保证这些线程共享处理器。,3.中断(NotRunnable)一个正在执行的线程可能被人为地中断,使其让出CPU的使用权,暂时中止自己的执行,进入阻塞状态。阻塞时它不能进入排队队列,只有当引起阻塞的原因被消除时,线程才可以转入就绪状态,重新进到线程队列中排队等待CPU资源,以便从原来终止处开始继续运行。进入中断状态的原因有如下几条:(1)调用了sleep()方法;(2)调用了suspend()方法;(3)为等候一个条件变量,线程调用wait()方法;(4)输入输出流中发生线程阻塞。4.死亡(Dead)处于死亡状态的线程不具有继续运行的能力。线程死亡的原因有两个,一个是正常运行的线程完成了它的全部工作,另一个是线程被提前强制性地终止。所谓死亡状态就是线程释放了实体,即释放分配给线程对象的内存。,线程的状态,13.1.3多线程的实现方法在Java中,创建线程的方法有两种:一种方法是通过创建Thread类的子类来实现,另一种方法是通过实现Runnable接口的类来实现,具体如下。方法一:定义一个线程类,它继承线程类Thread并重写其中的方法run(),这时在初始化这个类的实例时,目标target可为null,表示由这个实例来执行线程体。由于Java只支持单重继承,用这种方法定义的类不能再继承其他父类。方法二:提供一个实现接口Runnable的类作为一个线程的目标对象,在初始化一个Thread类或者Thread子类的线程对象时,把目标对象传递给这个线程实例,由该目标对象提供线程体run()。这时,实现接口Runnable的类仍然可以继承其他父类。,13.2通过继承Thread类实现多线程,例13-1程序清单TwoThreads_Test.javapublicclassTwoThreads_Testpublicstaticvoidmain(Stringargs)newThread_Test(线程1).start();/第一个线程的名字为线程1newThread_Test(线程2).start();/第二个线程的名字为线程2classThread_TestextendsThreadpublicThread_Test(Stringstr)super(str);/调用其父类的构造方法publicvoidrun()/重写run方法for(inti=0;i10;i+)/打印次数和线程的名字System.out.println(i+getName();try/线程睡眠,把控制权交出去sleep(int)(Math.random()*1000);catch(InterruptedExceptione)/线程执行结束System.out.println(执行结束!+getName();,13.3通过Runnable接口实现多线程,通过Runnable接口实现多线程的方法是首先设计一个实现Runnable接口的类,然后根据工作需要重新设计线程的run方法;再建立该类的对象,以此对象为参数建立Thread类的对象;调用Thread类对象的start方法启动线程,将执行权转交到run方法。,例13-2程序清单Runnable_Test.javaimportjava.applet.Applet;importjava.awt.Graphics;importjava.util.Date;publicclassRunnable_TestextendsAppletimplementsRunnable/实现接口Threadthread;publicvoidstart()if(thread=null)/线程体是Clock对象本身,线程名字为Clockthread=newThread(this,小时钟);thread.start();/启动线程publicvoidrun()/run()方法中是线程执行的内容while(thread!=null),repaint();/刷新显示画面trythread.sleep(1000);/睡眠1秒,即每隔1秒执行一次catch(InterruptedExceptione)publicvoidpaint(Graphicsg)Datenow=newDate();/获得当前的时间对象g.drawString(now.getHours()+:+now.getMinutes()+:+now.getSeconds(),5,10);/显示当前时间publicvoidstop()thread.stop();thread=null;,13.4线程的调度,Java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程。线程调度器按照线程的优先级决定应调度哪些线程来执行。正如我们前面所讲的:处于就绪状态的线程首先进入就绪队列排队等候处理器资源,同一时刻在就绪队列中的线程可能有多个。多线程系统会给每个线程自动分配一个线程的优先级,任务较紧急的重要线程,其优先级就较高;相反则较低。在线程排队时,优先级高的线程可以排在较前的位置,这样能优先享用到处理器资源,而优先级较低的线程则只能等到排在它前面的高优先级线程执行完毕之后才能获得处理器资源。对于优先级相同的线程,则遵循队列的“先进先出”的原则,即先进入就绪状态排队的线程被优先分配到处理器资源,随后才为后进入队列的线程服务。当一个在就绪队列中排队的线程被分配到处理器资源而进入运行状态之后,这个线程就称为是被“调度”或被线程调度管理器选中了。线程调度管理器负责管理线程排队和处理器在线程间的分配,一般都配有一个精心设计的线程调度算法。在Java系统中,线程调度依据优先级基础上的“先到先服务”原则。,下面几种情况下,当前线程会放弃CPU:线程调用了yield()或sleep()方法主动放弃;抢先式系统下,由高优先级的线程参与调度;时间片方式下,当前时间片用完,由同优先级的线程参与调度;由于当前线程进行I/O访问,外存读写,等待用户输入等操作,导致线程阻塞;或者是为等候一个条件变量,以及线程调用wait()方法。Thread类的setPriority(inta)方法可以设置线程优先级,使之符合程序的特定需要。a取值是:Thread.MIN_PRIORITY、Thread.MAX_PRIORITY、Thread.NORM_PRIORITY。线程的默认级别是Thread.NORM_PRIORITY。,例13-3程序清单ThreadPriority_Test.javaclassThreadPriority_Testpublicstaticvoidmain(Stringargs)Threadthread1=newMyThread(Thread1);thread1.setPriority(Thread.MIN_PRIORITY);/设置优先级为最小thread1.start();Threadthread2=newMyThread(Thread2);thread2.setPriority(Thread.MAX_PRIORITY);/设置优先级为最大thread2.start();Threadthread3=newMyThread(Thread3);thread3.setPriority(Thread.MAX_PRIORITY);/设置优先级为最大thread3.start();classMyThreadextendsThreadStringmessage;MyThread(Stringmessage)this.message=message;publicvoidrun()for(inti=0;i3;i+)/获得线程的优先级System.out.println(message+getPriority();,13.5线程的同步,13.5.1基本的线程控制1.终止线程线程终止后,其生命周期结束了,即线程进入死亡状态,终止后的线程不能再被调度执行,以下两种情况,线程将进入终止状态:(1)线程执行完其run()方法后,会自然终止。(2)通过调用线程的实例方法stop()来终止线程。2.测试线程状态可以通过Thread中的isAlive()方法来获取线程是否处于活动(Alive)状态;线程由start()方法启动后,直到其被终止之间的任何时刻,都处于活动状态。,3.线程的暂停和恢复有以下几种方法可以暂停一个线程的执行,在适当的时候再恢复其执行。(1)sleep()方法当前线程睡眠(停止执行)若干毫秒,线程由运行中状态进入不可运行状态,停止执行时间到后线程进入可运行状态。(2)suspend()和resume()方法线程的暂停和恢复,通过调用线程的suspend()方法使线程暂时由可运行态切换到不可运行态,若此线程想再回到可运行态,必须由其他线程调用resume()方法来实现。但从JDK1.2开始就不再使用suspend()和resume()。(3)join()方法当前线程等待调用该方法的线程结束后,再恢复执行。例如:TimerThreadtt=newTimerThread(100);tt.start();publicvoidtimeout()tt.join();/当前线程等待线程tt执行完后再继续往下执行,13.5.2多线程的同步实现在编写一个类时,如果该类中的代码可能运行于多线程环境下,那么就要考虑同步的问题。我们首先编写一个非常简单的多线程的程序,来模拟银行中的多个线程同时对同一个储蓄账户进行存款、取款操作。,13.6小结,本章我们学习了Java多线程机制,主要内容有:进程和线程的区别,线程的各种状态,多线程的实现方法,以及线程的调度,最后我们学习了线程的同步机制。线程在Java编程中有很重要的作用,通过本章的学习,读者要能利用线程机制进行简单的程序开发。,
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!