您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 企业文化 > 第13章龟兔赛跑――多线程
第13章龟兔赛跑——多线程能力目标:理解多线程、掌握线程的创建、启动、运行等方法。掌握线程优先级及其设置方法。理解线程状态,线程中断和线程同步等概念。能使用多线程编写龟兔赛跑程序和生产者消费者程序。/内容介绍13.1任务预览13.2程序、进程与线程13.3多线程13.4线程类Thread13.5线程同步与互斥13.6本章小结13.7实训13:龟兔赛跑、生产者与消费者/13.1任务预览本章实训程序运行结果:/13.2程序、进程与线程程序,是代码,是静态的。进程,是程序在计算机上的一次运行过程,进程是动态的。线程也是动态的,是比进程更小的概念,它是进程(程序运行过程)的一条执行路线。Java语言拥有多线程机制。java.lang包提供线程类Thread,只要定义继承Thread类的子类,并重写线程运行方法run。线程类的每一个对象都是一个线程,通过start方法启动。/【例13-1】编写龟兔赛跑多线程程序,设赛跑长度为100米,每跑完10米输出一次结果。classAnimalextendsThread{//线程类publicAnimal(Stringname){//构造方法,参数是线程名super(name);}publicvoidrun(){//线程运行方法for(inti=0;i=100;i+=10){if(this.getName().equals(乌龟)){System.out.println(\t\t乌龟跑了+i+米);}else{System.out.println(this.getName()+跑了+i+米);}try{Thread.sleep((long)(Math.random()*1000));}//休眠不超过1秒catch(InterruptedExceptione){}}}}/续例13-1publicclassExample1{//运行主类publicstaticvoidmain(String[]args){Animalrabbit=newAnimal(兔子);//线程(对象)1Animaltortoise=newAnimal(乌龟);//线程(对象)2rabbit.start();//启动线程1tortoise.start();//启动线程2}}/13.3多线程13.3.1构建Thread子类对象(1)编写Thread子类,即线程类,格式:class线程类名称extendsThread{...publicvoidrun(){...}//线程运行方法}如:classAnimalextendsThread{...}(2)构建线程对象。如:Animalrabbit=newAnimal(兔子);//线程(对象)1Animaltortoise=newAnimal(乌龟);//线程(对象)2(3)调用线程对象的start方法启动线程。如:rabbit.start();//启动线程1tortoise.start();//启动线程2注:主类main方法也是一条独立的执行路线(线程)。/13.3.2用实现Runnable接口的对象构建Thread对象(1)编写实现Runnable接口的类,格式:class类名extends父类implementsRunnable{...publicvoidrun(){...}//线程运行方法}(2)构建实现Runnable接口类的对象。如:newAnimal2(兔子“)newAnimal2(乌龟)(3)使用上述对象作参数,构造Thread对象。如:Threadrabbit=newThread(newAnimal2(兔子));Threadtortoise=newThread(newAnimal2(乌龟(4)最后调用start方法启动线程。/【例13-2】采用实现Runnable接口的方法编写龟兔赛跑多线程程序,功能与例13-1完全一样。classAnimal2implementsRunnable{privateStringname;publicAnimal2(Stringname){this.name=name;}publicStringgetName(){returnname;}publicvoidrun(){//线程运行方法for(inti=0;i=100;i+=10){if(this.getName().equals(乌龟)){System.out.println(\t\t乌龟跑了+i+米);}else{System.out.println(this.getName()+跑了+i+米);}try{Thread.sleep((long)(Math.random()*1000));}catch(InterruptedExceptione){}}}}…Threadrabbit=newThread(newAnimal2(兔子));Threadtortoise=newThread(newAnimal2(乌龟));rabbit.start();tortoise.start();…/13.4线程类Thread13.4.1Thread类构造方法及线程名称Thread类的类头声明:publicclassThreadextendsObjectimplementsRunnable每个线程对象都有名称,如果没有在构造方法中指定,则按“Thread-”+n的形式自动命名,也可用setName(Stringname)方法设定。常用构造方法:(1)Thread()。自动起名,用方法getName()获取线程名。(2)Thread(Stringname):要指定线程名作参数。(3)Thread(Runnabletarget):也是自动起名。(4)Thread(Runnabletarget,Stringname)。/13.4.2线程优先级与Thread相关字段线程有10个优先级,从高至低分别是10、9、…、1。中间级为5,它是线程默认的优先级。Thread类有3个关于优先级的整型静态常量字段:(1)MAX_PRIORITY:最大优先级,值是10。(2)MIN_PRIORITY:最小优先级,值是1。(3)NORM_PRIORITY,普通优先级,值是5。方法setPriority(intnewPriority)用于设置线程优先级,方法getPriority()用于获取线程优先级。/【例13-3】改进例13-1的龟兔赛跑程序,通过改变优先级,并减掉休眠时间,使得乌龟以迅雷不及掩耳的速度跑完100米。classAnimal3extendsThread{publicAnimal3(Stringname){super(name);}publicvoidrun(){for(inti=0;i=100;i+=10){if(this.getName().equals(乌龟)){…(\t\t乌龟跑了+i+米);}else{…(this.getName()+跑了+i+米);}}}}…Animal3rabbit=newAnimal3(兔子);rabbit.setPriority(Thread.MIN_PRIORITY);Animal3tortoise=newAnimal3(乌龟);tortoise.setPriority(Thread.MAX_PRIORITY);rabbit.start();tortoise.start();…/13.4.3线程生命周期与线程状态线程生存期间,存在6种状态:(1)NEW:新建状态。(2)RUNNABLE:运行状态,(3)BLOCKED:阻塞状态,(4)WAITING:等待状态,(5)TIMED_WAITING:定时等待状态,(6)TERMINATED:终止(死亡)状态,它们都是枚举常量,定义在Thread类嵌套枚举类型State。线程新建状态就表示为Thread.State.NEW,线程运行状态表示为Thread.State.RUNNABLE,等。线程运行过程中状态通过调用getState方法来获取。注:阻塞、等待和定时等待这3种可归纳为暂停状态,因此线程的状态又划分为新建、运行、暂停和死亡这4种状态。此外,线程还有一种称为“就绪”的状态,万事俱备,只欠CPU。为简单起见,就绪状态被纳入到运行状态中。线程是有生命,还可通过执行线程方法isAlive来判断。/13.4.4线程其它方法(1)currentThread:静态的获取当前正在执行线程对象引用方法。(2)sleep:静态线程休眠方法。调用休眠方法必须处理中断异常。(3)interrupt:中断(中途打断)线程方法。(4)activeCount:静态的当前活动线程数方法来自根类Object的与线程有关方法:Wait:等待方法。Notify:通知方法,这两个方法配套使用。notifyAll:通知所有等待线程方法。/【例13-4】编写兔子休眠后被乌龟中断(吵醒)的多线程程序。classAnimal4implementsRunnable{Threadrabbit,tortoise;publicAnimal4(){rabbit=newThread(this,兔子);tortoise=newThread(this,乌龟);}publicvoidrun(){//线程运行方法if(Thread.currentThread()==rabbit){try{System.out.println(兔子正在睡大觉...);rabbit.sleep(1000*60*2);//兔子休眠2小时}catch(InterruptedExceptione){System.out.println(兔子被叫醒);System.out.println(兔子开始跑步...);}}elseif(Thread.currentThread()==tortoise){System.out.println(乌龟大叫:跑步去!);rabbit.interrupt();//中断(吵醒)兔子线程System.out.println(乌龟开始跑步...);}}}/续13-4…ThreadmainThread=Thread.currentThread();Stringname=mainThread.getName();…(程序刚开始运行时的线程名:+name);…(name+线程状态:+mainThread.getState());…(当前活动线程数:+Thread.activeCount());Animal4animal=newAnimal4();…(兔子线程状态:+animal.rabbit.getState());…(乌龟线程状态:+animal.tortoise.getState());animal.rabbit.start();…(兔子线程状态:+animal.rabbit.getState());animal.tortoise.start();…(乌龟线程状态:+animal.tortoise.getState());…(当前活动线程数:+Thread.activeCount());…/13.5线程同步与互斥13.5.1同步关键字synchronized临界资源:在某一时刻只能独占使用(互斥)、在不同时刻又允许多人共享的资源。例子:公司的银行账户,由公司授权多人存、取钱,但每次只允许一个人存取。手机等产品,先由生产者生产,后才卖给消费者,一个产品不能同时处于生产和消费中。线程的同步和互斥:处理临界资源,涉及多线程之间相互协作(步骤协调)。synchronized修饰的方法,犹如对临界资源加“锁”,令方法执行过程对临界资源进行“同步”(协同好步骤)操作。synchronized还可直接锁定一个临界资源,语法:synchronized(临界资源对象){操作代码}/【例13-5】编写对银行账户临界资源的进行同步操作的多线程程序。classAccount{//银行账户(临界资源)类privat
本文标题:第13章龟兔赛跑――多线程
链接地址:https://www.777doc.com/doc-3225236 .html