Java程序设计教程课件:Java多线程_第1页
Java程序设计教程课件:Java多线程_第2页
Java程序设计教程课件:Java多线程_第3页
Java程序设计教程课件:Java多线程_第4页
Java程序设计教程课件:Java多线程_第5页
已阅读5页,还剩34页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Java多线程Java

Java

多线程处理机制线程的生命周期创建线程的方法线程同步线程联合

守护线程

本章内容提要

…0在程序设计中,经常会遇到多个任务同时执行的情况,这种资源被交替占用的任务执行

过程,被称为多线程处理,其中,每个任务一

次动态执行过程被称为进程。进程执行过程中

的暂停被称为中断。进程通过中断被分解成了

若干段,每一段被称为一个线程。10.1Java多线程处理机制在Java语言的运行环境中(JVM),

置了一个线程调度器,用于确定某一时刻由哪一

个线程占用计算机资源进行执行,从而实现了

多线程操作。当Java程序开始运行时

,main()

方法首先执行,此时线程调度器会开启一个线

程,即为主线程

(Java

Applet的主线程是Web

浏览器)

,

责main()方法的执行,除主线程

之外的线程被称为其它线程。10.1Java多线程处理机制10.2线程的生命周期Java线程从最初的创建直至最后执行的结束,需要遵循一个生命周期。利用生命周期,使得线程更加容易被分析和控制。线程的生命周期分为四个阶段一新建、运行、中断、死亡。转换过程如下图:新建

入队

等待队列

出队

运行执行结束中断解除

导致中断中断

死亡图10.1线程生命周期线程对象定义后,线程直接进入新建状态。处于

新建状态的线程不占用计算机资源。2.

运行当线程占用计算机资源时,就进入了运行状态。

线程由新建状态转入运行状态并不是直接完成的,需

要进入一个由进程调度器控制的等待队列,等待计算

机资源的闲置(被其它线程释放),当计算机资源闲

置时

,依据队列的先进先出性,最先进入等待队列的

线程最先出队,获得计算机资源,转入运行状态。10.2线程的生命周期1.新建3.

断处于运行状态的线程必须在运行一段时间后让出计算机资源,这就是线程的中断。中断

原因包括:》阻

塞》线程调度器的控制》通过sleep(long

mill)方法》通过wait()方法10.2线程的生命周期当线程中断解除时(例如:通过Scanner类的方法输入了数据、经

过mill

毫秒后休眠结束),线

程并不会立刻返回运行状态,而是重新进入等待队

列进行排队,并依据队列先进先出的使用原则,占

用计算机资源,进入运行状态。4

.

死亡线程执行完毕后,就进入了最后的死亡状态,

线程的生命周期同时结束。10.2线程的生命周期Java

多线程的实现是通过创建线程对象开始的。线程对象的创建有两种方法一利用Thread类的子类创建线程和使用Runnable接口创建线程。两种方法相比,第一种较为简单,

第二种更加灵活。10.3创建线程的方法1.利用Thread

类的子类创建线程Thread类位于java.lang

包中,是Java语

言提供的线程类。定义一个继承Thread类的

子类,在该类中重写Thread类中的publicvoid

run()方法,当子类对象一线程对象获

得资源时,会调用run()方法,执行线程操作。10.3创建线程的方法10.3创建线程的方法例10-1classSimpleThreadextendsThread{

publicvoidrun(){Sysntln(getName()+i);sleep((int)(Math.random()*1000));}catch(InterruptedExceptione){Sysntln(e);Sysntln("DONE!"+getName());for(int

i=0;i<3;i++){try{class

Example10_1{public

static

void

main(String

args[){SimpleThreadone=newSimpleThread();

one.setName("oneThread");one.start();SimpleThreadtwo=newSimpleThread();

two.setName("twoThread");two.start();10.3创建线程的方法2.使用Runnable接口对象创建线程利用Thread类定义直接线程对象,此时,调用

的Thread类的构造方法需要设置一个对象做参数,

而定义该对象的类必须实现jRunnable接口,这个

对象被称为线程对象的目标对象。Runnable接口中

定义了public

void

run()方法,定义目标对象的

类使用了Runnable接口,必须重写其中的publicvoidrun()方法。10.3创建线程的方法例10-2import

jDate;importjGraphics;publicclass

Example10_2extendsjApplet

implements

Runnable{ThreadclockThread;publicvoidstart(){if(clockThread==null){clockThread=newThread(this,"Clock");

clockThread.start();10.3创建线程的方法publicvoid

run(){while(clockThread

I=null){int();clockThread.sleep(1000);}catch(InterruptedExceptioneSysntln(e);tryrep10.3创建线程的方法publicvoidpaint(Graphicsg){

Date

now=new

Date();g.drawString(now.toString(),5,10);public

void

stop({clockThread.stop();clockThread=null;10.3创建线程的方法10.3创建线程的方法3.线程常用操作方法public

void

start()使线程进入等待队列public

void

run()使线程进入运行状态public

boolean

isAlive()判断线程是否处于运行状态public

static

void

sleep(long

mill)使正在运行的线程休眠(中断)mill

毫秒publicstaticThreadcurrentThread()获取正在运行的线程对象public

void

interrupt()吵醒正在休眠的线程10.3创建线程的方法■例10-3■publicclassThreadMethodimplements

Runnable{

Thread

liLei,fire

,alarm;■

ThreadMethod(){liLei=new

Thread(this);public

void

run(){long

time=0;while(true){if(Thread.currentThread()==liLei)Sysntln("李雷今天太累了,抽着烟睡着了

……

.");try{fire

=new

Thread(this);fire.start();Thread.sleep(1000*60*60);}catch(InterruptedException

e){Sysntln("

李雷被报警声叫醒了!");errupt();return;}else

if(Thread.currentThread()==fire){if(time==0){Sysntln("

李雷的烟头点燃了地毯,李雷还在睡10.3创建线程的方法try{fire

=new

Thread(this);fire.start();Thread.sleep(1000*60*60);}catch(InterruptedException

e){Sysntln("

李雷被报警声叫醒了!");

errupt();return;}else

if(Thread.currentThread()==fire){

if(time==0){Sysntln("

李雷的烟头点燃了地毯,李雷还在睡10.3创建线程的方法10.3创建线程的方法time=2000;try{Thread.sleep(time);}catch(InterruptedExceptione){Sysntln(e);}else

if(time>0&&time<3000){Sysntln("地毯着火了,李雷还没醒!!!");

time=4000;try{Thread.sleep(time);}catch(InterruptedExceptione){Sysntln(e);}else

if(time>3000){Sysntln("

火势越来越大……");alarm=new

Thread(this);alarm.start();try{Thread.sleep(time);}catch(InterruptedExceptione){Sysntln("扑灭了地毯上的火,吸烟真是危险啊!");return;}else

if(Thread.currentThread()==alarm){Sysntln("报警器被触发啦!");10.3创建线程的方法10.3创建线程的方法Thread.sleep(500);

}catch(InterruptedExceptione)Sysntln(e);liLerrupt();return;class

Example10_3{publicstaticvoidmain(String)args{ThreadMethodmethod=newThreadMethod();metrt();try{■4.多线程中的共享与独享当多个线程使用同一个目标对象时,它们都

将利用目标对象所属类中重写的run()方法进行线程

的执行。此时,如果run()

方法中使用了类中的成员

变量,那么该成员变量的操作对每个线程都是开放

的一目标对象的成员变量被多个线程的访问共享。但是,对于run()方法中定义的局部变量,由于其是

在每个线程调用run()

方法时被分配内存空间,调

结束后又立即释放内存空间,因此仅被每个线程的

访问独享。10.3创建线程的方法class

SavingBox

implements

Runnable{double

balance;publicvoid

run(){int

count=0;while(true){balance=balance+1000;count++;try{Sysntln(Thread.currentThread().getName()+"第"+count+”次存钱,存钱盒目前有"+balance+"元。");if(count==3){Sysntln(Thread.currentThread().getName()+存了"+count+"次,本月存钱结束。");10.3创建线程的方法Thread.sleep(2000);}catch(InterruptedExceptione){Sysntln(e);}}public

class

Example10_4{public

static

void

main(String[]args)SavingBoxbox=newSavingBox();Thread

liLei=newThread(box);liLei.setName("李雷");Thread

hanMeiMei=newThread(box);

hanMeiMei.setName(“韩梅梅”);liLei.start();10.3创建线程的方法return;

10.4线程同步

使用相同目标对象的线程会共享目标对象的成员变量,有时这种情况需要避免,即当一个线

程访问共享成员变量时,即使该线程因休眠而中断,其它线程也需要等待,直到访问结束,其它

线程才可以进行访问,这种情况被称为线程同

或线程级安全。要实现线程同步,需要使用synchronized关键字修饰共享成员变量的访问方法,这个方法被称为同步方法。

10.4线程同步

同步方法中,sleep()方法的调用不会引起中断

。此

,若想通过程序设计中断同步,只能通

过Thread类中的wait()方法完成,而解除wait()

方法的中断需调用notifyAl1()方法。notifyAl1()方法会使所有因wait()方法调用而中

断的线程结束中断,按“先中断先入队”的原则进入等待队列,等待资源的空闲,准备从中断位

置继续执行。

10.4线程同步

例10-5classAccount{doublebalance;publicsynchronizedvoiddeposit(doublemoney){balance=balance+money;Sysntln("存入"+money+"

元,账户余额"+balance+"元。");Thread.sleep(1000);}catch(InterruptedExceptione){Sysntln(e);notifyAll();try{

10.4线程同步

publicsynchronizedvoidwithdraw(doublemoney){}catch(InterruptedExceptione){Sysntln(e);balance=balance-money;Sysntln("取出"+money+"元,账户余额"+balance+"元。while(balance<money){Sysntln("账户余额不足,等待存款。");try{

wait();

10.4线程同步

classSynchroTest

implements

Runnable{Thread

liLei,hanMeiMei;Accountaccount;SynchroTest(){liLei=new

Thread(this);hanMeiMei=newThread(this);account=new

Account();publicvoid

run(){if(Thread.currentThread()==liLei){for(int

i=1;i<=3;i++){Sysntln("李雷挣钱,将工资悉数存入家庭银行

.");account.deposit(1000);try{

10.4线程同步

Thread.sleep(2000);}catch(InterruptedExceptione){Sysntln(e);

(

(i

r;

3.c;

tThread()==hanMeiMei){Sysntln("韩梅梅把握家中的开支,从家庭银行取钱……");account.withdraw(800);publiccl

ss

Example10_5{publicstaticvoidmain(String[]args){SynchroTestsynchro=newSynchroTest();syncrt();syncrt();}aJ1hinte

iforels

10.5线程联合

当一个线程正在运行时,可以与另一个线程进

行联合,此时

,正在运行的线程会中断执行,将计

算机资源交给联合的线程,直到联合的线程运行结

束,才会结束中断,进入等待队列排队,准备获取计算机资源,恢复运行。线程对象调用join()方法,表示进行线程联合操作。由于join()方法声明

了InterruptedException

异常,因此在方法调用位

置需要进行异常捕获。例子10-6演示了线程联合。

10.5线程联合

例10-6classThreadJoinTest

implements

Runnable{Threadtourist,policeOffice;ThreadJoinTest(){tourist=newThread(this);tourist.setName(”李雷");publicvoid

run(){if(Thread.currentThread()==tourist){Sysntln("李雷计划去国外旅游,需要先到警察局办理护Thread.sleep(1000);policeOffice=newThread(this);policeOffice.start();policeOffice.join();try{

10.5线程联合

}catch(InterruptedExceptione){Sysntln(e);Sysntln("李雷拿到了护照,可以去办理签证,准备出国了。");

}elseif(Thread.currentThread()==policeOffice){try{Sysntln("李雷来到警察局正在填写申请表…….");Thread.sleep(1000);Sysntln("照相…….");Thread.sleep(1000);Sysntln("将申请表和照片交给警察审核…….");

10.5线程联合

Thread.sleep(1000);Sysntln("审核通过,交款,15个工作日后领取护照!");Thread.sleep(2000);}catch(InterruptedExceptione){■

Sysntln(e);■publicclass

Example10_6{■publicstatic

void

main(String[]args)ThreadJoinTest

joinTest=

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论