ImageVerifierCode 换一换
格式:DOCX , 页数:20 ,大小:123.93KB ,
资源ID:19133004      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/19133004.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(JAVA多线程详解文档格式.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

JAVA多线程详解文档格式.docx

1、一个线程“创建工作死亡”的过程称为线程的生命周期。线程生命周期共有五个状态:新建状态、就绪状态、运行状态、阻塞状态和死亡状态。1. 新建状态新建状态是指创建了一个线程,但它们还没有启动。处于新建状态的线程对象,只能够被启动或者终止。例如,以下代码使线程myThread处于新建状态:Thread myThread=new Thread();2. 就绪状态就绪状态是当线程处于新建状态后,调用了start()方法,线程就处于就绪状态。就绪状态线程具备了运行条件,但尚未进入运行状态。处于就绪状态的线程可以多个,这些就绪状态的线程将在就绪队列中排队,等待CPU资源。就绪状态的线程通过线程调度获得CPU资

2、源变成运行状态。例如,以下代码使myThread处于就绪状态。myThread.start();3. 运行状态运行状态是某个就绪状态的线程获得CPU资源,正在运行。如果有更高优先级的线程进入就绪状态,则该线程将被迫放弃对CPU的控制器,加入就绪状态。使用yield()方法可以使线程主动放弃CPU。线程也可能由于结束或执行stop()方法进入死亡状态。每个线程对象都有一个run()方法,当线程对象开始执行时,系统就调用对象的run()方法。4. 阻塞状态柱塞状态是正在运行的线程遇到某个特殊情况。例如,延迟、挂起、等待I/O操作完成等,进入柱塞状态的线程让出CPU,并暂时停止自己的执行。线程进入柱

3、塞状态后,就一直等待,直到引起柱塞的原因被消失,线程有转入就是状态,重新进入就绪列队排列。当线程再次变成运行状态时,将从暂停处开始继续运行。线程从柱塞状态恢复到就绪状态,有三种途径:(1) 自动恢复:(2) 用resume()方法恢复:(3) 用notif()或nitifyAll()方法通知恢复。也可能因为别的线程强制某个处于阻塞状态的线程终止,该线程就从阻塞状态进入死亡状态。5. 死亡状态死亡状态是指线程不再具有继续运行的能力,也不能再转到其他状态。一般有两种情况使一个线程终止,进入死亡状态。(1) 线程完成了全部工作,即执行完run()方法的最后一条语句。(2) 线程被提前强制性终止。图8

4、.1是线程的生命周期图,图中给出从一种状态转变成另一种状态的各种可能的原因。8.1.2 线程调度与优先级Java提供一个线程调度器来监视和控制就绪状态的线程。线程的调度策略采用抢占式,优先级高的线程比优先级低的线程优先执行。在优先级相同的情况下,就按“先到先服务”的原则。线程的优先级用数值表示,数值越大优先级越高(范围110)。每个线程根据继承特性自动从父进程获得一个线程的优先级,也可在程序中重新设置。对于任务较紧急的重要线程,可安排较高的优先级。相反,则给一个较低的优先级。每个Java程序都有一个默认的主线程,就是通过JVM(Java Virtual Machine,Java虚拟机)启动的第

5、一个线程。对于应用程序,主线程执行的是main()方法。对于Applet,主线程是指浏览器加载并执行小应用程序的哪一个线程。子程序是由应用程序创建的线程。另有一种线程称为守护线程(Daemon),这是一种用于监视其他线程工作的服务线程,它的优先级最低。8.2 Thread类和Runnable接口Java程序实现多线程应用有两种途径: 一是继承Thread类声明Thread子类,用Thread子类创建线程对象。 二是在类中实现Runnable接口,在类中提供Runnable接口的run()方法。无论用哪种方法,都需要Java基础类库中的Thread类及其方法的支持。程序员能控制的关键性工作有两个

6、方面: 一是编写线程的run()方法; 二是建立线程实例。8.2.1 Thread类Thread类是用来创建线程和提供线程操作的类。1. Thread类提供的方法Thread类为创建线程和线程控制提供以下常用的方法:(1) Thread(),创建一个线程。线程名按创建顺序为Thread_1、Thread_2等。(2) Thread(String m),创建一个以m命名的线程。(3) Thread(Runnable target),创建线程,参数target是创建线程的目标。目标是一个对象,对象的类要实现Runnable接口,类中给出接口的run()方法。(4) public Thread(Ru

7、nnable target,String m),创建线程,参数target是创建线程的目标。m是线程名。(5) Thread(ThreadGroup g,String m),创建一个以m命名的线程,该线程属于指定的线程组g。(6) Thread(ThreadGroup g,Runnable target),创建一个属于指定线程组g的线程,target是线程的目标。(7) Thread(ThreadGroup g,Runnable target,String m),创建一个线程,名为m,属于指定线程组g,target是线程的目标。(8) getPriority(),获得线程的优先级。(9) se

8、t Priority(int p),设定线程的优先级为p。线程创建时,子线程继承父线程的优先级。优先级的数值越大优先级越高(缺省是5)。常用以下3个优先级: Thread.MIN_PRIORITY(最低) Thread.MAX_PRIORITY(最高) Thread.NORM_PRIORITY(标准)(A) start(),启动线程,让线程从新建状态到就绪状态。(B) run(),实现线程行为(操作)的方法。(C) sleep(int dt)让线程休眠dt时间,单位是毫秒。例如代码 sleep(100);让线程休眠100毫秒时间段。在以后的这个时间段中,其他线程就会有机会被执行。当休眠时间一到

9、,将重新到就绪队列排序。由于sleep()方法可能会产生Interrupt Expiration异常,应将sleep方法写在try块中,并用catch块处理异常。sleep()方法是static方法,不可重载。(D) currentThread(),获得当前正在占有CPU的能个线程。(E) getName(),获取线程的名字。(F) setName(),设置线程的名字。(G) isAlive(),返回boolean类型值,查询线程是否还活跃。(H) destroy(),强制线程生命周期结束。(I) stop(),强制线程生命周期结束,并完成一些清理工作,及抛出异常。有时,小应用程序的界面已从屏

10、幕消失,但并没有停止线程的执行,会一直到浏览器关闭才结束。因此要在小应用程序的stop()方法中终止线程的执行。(J) suspend(),挂起线程,处于不可运行的阻塞状态。(K) resume(),恢复挂起的线程,重新进入就绪队列排队。(L) yield(),暂停当前正在执行的线程,若就绪队列中有与当前线程同优先级的线程,则当前线程让出CPU控制权,移到就绪队列的队尾。若队列中没有同优先级或更高优先级的线程,则当前线程继续执行。2. 用Thread子类实现多线程用Thread子类实现多线程,得先声明一个Thread类的子类,并在子类中重新定义run()方法。当程序需要建立线程时,就可以创建T

11、hread子类的实例,并让创建的线程调用start()方法,这时,run()方法将自动执行。【例8.1】应用程序用Thread子类实现多线程。在main()方法中创建了两个线程threadA和threadB,它们分别是Thread子类threadA和threadB的实例,并分别调用它们的start()方法启动它们。threadA先调用start()方法,类threadA中的run()方法将自动执行。由于threadA线程先执行,它的run()方法输出“我是threadA”和当时的时间后,threadA线程主动休息2000毫秒,让出CPU。这时正在等待CUP的threadB线程获得CPU资源,执

12、行它的run()方法,输出“我是threadB”和当时的时间,threadB线程主动让出CPU,1000毫秒后又来排队等待CPU资源。过了1000毫秒后,这时threadA线程还没有“醒了”,因此有轮到threadB执行。再次输出“我是threadB”import java.util.Date;public class Example8_1 static Athread threadA; static Bthread threadB; public static void main(String args) threadA=new Athread(); threadB=new Bthread(

13、); threadA.start(); threadB.start(); class Athread extends Thread public void run() Date timeNew; /为了能输出当时的时间 for(int i=0;i=5;i+) timeNew=new Date(); System.out.println(我是threadA:+timeNew.toString(); try sleep(2000); catch(InterruptedException e) class Bthread extends Thread我是threadB: sleep(1000);以下

14、是例8.1程序执行的输出结果,从输出清单中可发现两线程的输出频度的差异。Thu Feb 16 17:26:06 CST 201207 CST 201208 CST 201209 CST 201210 CST 201211 CST 201212 CST 201214 CST 201216 CST 20128.2.2 Runnable接口Java.lang.Runnable接口,只有run()方法需要实现。一个实现Runnable接口的类数据上定义了一个在主线程之外的新线程的操作。用Runnable接口实现多线程的主要工作是:声明实现Runnable接口的类,在类内实现run()方法;并在类内声明

15、线程对象,在init()方法或start()方法中创建新线程,并在start()方法中启动新线程。【例8.2】小应用程序通过Runnable接口创建线程。在类的start()方法中用构造方法Thread(this)创建了一个新的线程。this代表着该类的对象作为新线程的目标,因此类必须为这个新创建的线程实现Runnable接口,即提供run()方法。在start()方法中构造了一个名为myThread的线程,并调用Thread类的start()方法来启动这个程序。这样,run()方法被执行,除小应用程序的主线程外,又开始了一个新线程myThread。在例子中,run()方法在睡眠1秒后,调用r

16、epaint()方法重绘Applet窗口。在paint()方法中,在文本区输出线程睡眠的次数,并用随机产生的颜色和半径涂一个圆块。import java.applet.*;import java.awt.*;import javax.swing.*;public class Example8_2 extends Applet implements Runnable Thread myThread=null; /声明一个线程对象 JTextArea t;int k; public void start() t=new JTextArea(20,20); add(t);k=0;setSize(50

17、0,400); if(myThread=null) /重新进入小程序时,再次创建线程myThread myThread=new Thread(this); /创建新线程 myThread.start(); /启动新线程 while(myThread!=null) myThread.sleep(1000);k+; repaint(); public void paint(Graphics g) double i=Math.random(); if(i=360) redSeta=0; redPen.setColor(Color.red); tryredBall.sleep(20); catch(I

18、nterruptedException e) else if(Thread.currentThread()=blueBall) x=(int)(80.0*Math.cos(3.1415926/180.0*blueSeta); y=(int)(80.0*Math.sin(3.1415926/180.0*blueSeta); bluePen.setColor(Color.gray); bluePen.fillOval(150+x, 100+y, 10, 10); blueSeta-=3; if(blueSeta=360) blueSeta=0; bluePen.setColor(Color.blu

19、e); 8.3 线程互斥和同步通常情况下,程序中的多个线程是相互协调和相互联系的,多线程之间有互斥和同步。8.3.1 线程互斥先看线程之间需要互斥的情况。设有若干线程共享某个变量,且都对变量有修改。如果它们之间不考虑相互协调工作,就会产生混乱。比如,线程A和B共有变量x,都对x执行增1操作。由于A和B没有协调,两线程对x的读取、修改和写入操作会相互交叉,可能两个线程读取同样的x值,一个线程将修改后的x新值写入到x后,另一个线程也把自己对x的修改后的新值写入到x。这样,x只记录一个线程的修改作用。【例8.4】应用程序说明多线程共享变量,因设有互相协调生产不正确结果。主线程创建了20个线程,它们都

20、取变量的值,经累加后,将新值存回变量。待这些线程执行结束,产生不正确的结果。public class Example8_4 MyResourceClass mrc=new MyResourceClass(); Thread aThreadArray=new Thread20; System.out.println(t刚开始的值是:+mrc.getInfo();t预期的正确结果是:+20*1000*50);t多个线程正在工作,请稍等!20; aThreadArrayi=new Thread(new MyMultiThreadClass(mrc); aThreadArrayi.start(); WhileLoop: while(true) for(int i=0;i+) if(aThreadArrayi.isAlive() continue WhileLoop; break;t最后的结果是:class MyMultiThreadClass implements Runnable MyResourceClass UseInteger; MyMultiThreadClass(MyResourceClass mrc) UseInteger=mrc; public void r

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1