文学学习课件.pptx
Java的多线程机制1主要内容线程的概念线程的生命周期Java中多线程的编程继承Thread类与使用Runnable接口Thread类的主要方法线程的同步与死锁动画第1页/共37页Java的多线程机制2基本概念之一:进程进程是正在运行的一个程序程序:静态对象进程:动态过程操作系统为每个进程分配一段内存空间,包括:代码、数据以及堆栈等资源多任务的操作系统(OS)中,进程切换对CPU资源消耗较大第2页/共37页Java的多线程机制3基本概念之二:多线程单线程多线程进程传统进程多线程进程第3页/共37页Java的多线程机制4基本概念之二:多线程线程是比进程更小一级的执行单元线程不能独立存在,必须存在于进程中,各线程间共享进程空间的数据线程创建、销毁和切换的负荷远小于进程,又称为轻量级进程(lightweight process)。第4页/共37页Java的多线程机制5线程的调度调度策略时间片抢占式:高优先级的线程抢占CPU Java的调度方法同优先级线程组成先进先出队列,使用时间片策略对高优先级,使用优先调度的抢占式策略 12第5页/共37页Java的多线程机制6线程的生命周期新创建运行状态阻塞状态死亡状态start()start()new()new()sleep()sleep()睡眠时间到等待I/OI/OI/OI/O完成wait()wait()notify()notify()notifyAll()notifyAll()对象锁定锁释放异常退出runrun方法退出第6页/共37页Java的多线程机制7线程的生命周期(续)Newborn:线程已创建,但尚未执行Runnable:(就绪)线程已被调度,按优先级和先到先服务原则在队列中排队等待CPU时间片资源Runnnig:正在运行Blocked:(阻塞)因某事件或睡眠而被暂时性地挂起Dead:正常/强行中断,退出运行状态第7页/共37页Java的多线程机制8Java对多线程的支持提供用户级的多线程支持Thread类start(),stop(),run()Runnable 接口实现多线程的两种编程方法继承 Thread 类实现 Runnable 接口第8页/共37页Java的多线程机制9方法之一:继承Thread类Thread类的重要方法:run()定义线程的具体操作系统调度此线程时自动执行初始时无具体操作内容如何编程呢?继承Thread类,定义 run()方法第9页/共37页Java的多线程机制10Easy?Lets try it!小例子:SimpleThread.javaTwoThreadsTest.java第10页/共37页Java的多线程机制11public class SimpleThread extends Thread public SimpleThread(String str)super(str);/创建具以str为名字的线程 public void run()/定义run()方法 for(int i=0;i 10;i+)System.out.println(i+getName();try /休眠一段时间 sleep(int)(Math.random()*1000);catch(InterruptedException e)System.out.println(DONE!+getName();/SimpleThread.javapublic class TwoThreadsTest public static void main(String args)new SimpleThread(Take it myself?).start();new SimpleThread(Give it to police!).start();/TwoThreadsTest.java第11页/共37页Java的多线程机制12Thread类java.lang包构造函数Thread();无参数Thread(String threadname);指定线程实例名线程的优先级控制三个常量:MAX(10),MIN(1),NORM_PRIORITY(5)getPriopty(),setPriopty(int nP)线程创建时继承父线程的优先级第12页/共37页Java的多线程机制13Thread类的有关方法start():由Newborn到Runnable启动线程run():线程在被调度时执行的操作sleep(指定时间):令当前活动线程在指定时间段内放弃对CPU控制,使其他线程有机会被执行,时间到后重排队产生例外InterruptedException用try块调用sleep(),用catch块处理例外第13页/共37页Java的多线程机制14Thread类的有关方法(续)suspend():挂起线程,处于阻塞状态resume():恢复挂起的线程,重新进入就绪队列排队应用:可控制某线程的暂停与继续方法:设一状态变量suspendStatus=false(初始)暂停:if(!suspendStatus)T.suspend();suspendStatus=true;继续:if(suspendStatus)T.resume();suspendStatus=false;第14页/共37页Java的多线程机制15Thread类的有关方法(续)yield():对正在执行的线程若就绪队列中有与当前线程同优先级的排队线程,则当前线程让出CPU控制权,移到队尾若队列中没有同优先级的线程,忽略此方法stop()强制线程生命期结束isAlive():返回boolean,表明是否还存在第15页/共37页Java的多线程机制16Thread类方法总结启动线程:start()有关线程执行的控制:stop()、suspend()、resume()有关调度控制Thread.sleep(10);/低优先级的线程也可以获得执行Thread.yield();/同优先级的线程可以获得执行suspend();/暂停本线程第16页/共37页Java的多线程机制17方法之二:RunnableRunnable接口任何线程类都必须要实现的一个接口,Thread类也不例外run()方法方法二:自定义类实现Runnable接口自定义类实现Runnable接口使用Thread类的另一构造函数:Thread(Runnable,String)使用start()启动线程第17页/共37页Java的多线程机制18方法之二:Runnable(续)例:class A implements Runnablepublic void run().class B public static void main(String arg)Runnable a=new A();Thread t=new Thread(a);t.start();第18页/共37页Java的多线程机制19方法之二:Runnable(续)两种方法的选择当需要从其他类,如Applet类继承时,使用Runnable当编写简单的程序时,可考虑使用继承Thread类例:RaceApplet.java具体运行结果(线程调度)与平台有关第19页/共37页Java的多线程机制20public class Runner extends Thread /赛跑者线程类 public int tick=1;public void run()while(tick 40000000)tick+;/Runner.java/RaceApplet是一个实现了多线程的Appletpublic class RaceApplet extends Applet implements Runnable final static int NUMRUNNERS=2;/定义赛跑线程的个数 final static int SPACING=20;/声明两个赛跑线程 Runner runners=new RunnerNUMRUNNERS;/声明一个画图线程 Thread updateThread=null;第20页/共37页Java的多线程机制21 public void init()/重载Applet的init()方法 for(int i=0;i NUMRUNNERS;i+)runnersi=new Runner();/创建赛跑线程线程 runnersi.setPriority(i+1);/设优先级first=1,second=2 if(updateThread=null)/创建绘图线程,并设优先级为3 updateThread=new Thread(this,Thread Race);updateThread.setPriority(NUMRUNNERS+1);addMouseListener(new MyAdapter();/注册事件监听者 /end of init()第21页/共37页Java的多线程机制22 /内部事件监听者类,监听鼠标事件 class MyAdapter extends MouseAdapter /鼠标点击后,开始赛跑及绘制线程 public void mouseClicked(MouseEvent evt)if(!updateThread.isAlive()updateThread.start();/启动绘制线程 for(int i=0;i NUMRUNNERS;i+)if(!runnersi.isAlive()runnersi.start();/启动赛跑线程 /end of class MyAdapter第22页/共37页Java的多线程机制23 public void paint(Graphics g)/paint()方法中绘制框架 /end of paint()/update()方法中绘制赛跑者的进度,可以消除图画的闪烁 public void update(Graphics g)for(int i=0;i NUMRUNNERS;i+)/画两条线 g.drawLine(SPACING,(i+1)*SPACING,SPACING+(runnersi.tick)/100000,(i+1)*SPACING);/end of update()第23页/共37页Java的多线程机制24 public void run()/实现Runnable接口的run()方法 while(true)repaint();/重新绘制,自动调用update()方法 try Thread.sleep(10);/休眠,把执行机会让给低优先级线程 catch(InterruptedException e)/end of run()public void stop()/重载Applet的stop()方法 for(int i=0;i NUMRUNNERS;i+)if(runnersi.isAlive()runnersi=null;/中止赛跑线程 if(updateThread.isAlive()updateThread=null;/中止绘图线程 /end of stop()/RaceApplet.java第24页/共37页Java的多线程机制25同步问题的提出线程执行的不确定性引起执行结果的不稳定如线程A:A1A2线程B:B1B2线程对内存、数据的共享如push(a):i+;numi=a pop():取出numi;i-;问题的解决同步:用synchronized关键字前缀给针对共享资源的操作加锁;同步方法、同步块synchronized void push()synchronized int pop()实现机制:管程第25页/共37页Java的多线程机制26线程的协调与通讯线程间需协调与通讯:生产者/消费者问题wait()与notify()Object类的方法:public final voidwait():令当前线程挂起并放弃管程,同步资源解锁,使别的线程可访问并修改共享资源,而当前线程排队等候再次对资源的访问notify()唤醒正在排队等待资源管程的线程中优先级最高者,使之执行并拥有资源的管程wait()+notify()+标志变量:可协调、同步不同线程的工作第26页/共37页Java的多线程机制27线程的协调与通讯(续)Wait_Notify 程序CubbyHole.java创建用户的线程子类Producer:产生数据(存数据);Consumer:消费数据(取数据)CubbyHole类,共享数据区,同步方法put(int value)方法int get()方法主类中创建共享数据对象,并启动两线程第27页/共37页Java的多线程机制28class CubbyHole private int seq;/共享数据 private boolean available=false;/条件标志变量 public synchronized int get()/取数据的同步方法get()while(available=false)trywait();/条件不符合,则wait catch(InterruptedException e)available=false;/修改条件notify();/通知唤醒其他等待管程的线程return seq;/返回要取出的数值 /end of get()第28页/共37页Java的多线程机制29/存放数据的同步方法put()public synchronized void put(int value)while(available=true)trywait();/条件不符合,则wait catch(InterruptedException e)seq=value;/把共享变量修改为要放置的数据available=true;/修改条件notify();/通知唤醒其他等待管程的线程 /end of put()/end of class CubbyHole第29页/共37页Java的多线程机制30class Producer extends Thread /生产者线程类 private CubbyHole cubbyhole;private int number;public Producer(CubbyHole c,int number)cubbyhole=c;this.number=number;public void run()/定义run()方法 for(int i=0;i 10;i+)/共产生10个 cubbyhole.put(i);System.out.println(Producer#+this.number+put:+i);try sleep(int)(Math.random()*100);catch(InterruptedException e)/end of class Producer第30页/共37页Java的多线程机制31class Consumer extends Thread /消费者线程类 private CubbyHole cubbyhole;private int number;public Consumer(CubbyHole c,int number)cubbyhole=c;this.number=number;public void run()/定义run()方法 int value=0;for(int i=0;i 10;i+)/不间断的连续消费10个 value=cubbyhole.get();System.out.println(Consumer#+this.number+got:+value);/end of class Consumer第31页/共37页Java的多线程机制32class ProducerConsumerTest /主类:测试 public static void main(String args)CubbyHole c=new CubbyHole();/the shared data object Producer p1=new Producer(c,1);/Producer线程 Consumer c1=new Consumer(c,1);/Consumer线程 p1.start();/启动生产者线程 c1.start();/启动消费者线程 /end of ProducerConsumerTest程序执行结果:生产者线程和消费者线程严格地轮流执行,获得了线程间的协调执行。第32页/共37页Java的多线程机制33线程的死锁死锁不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,就形成了线程的死锁如:哲学家问题(thinking or eating)解决方法专门的算法、原则尽量减少同步资源的定义第33页/共37页Java的多线程机制34动画即若干幅相近的图片接连显示例:旋转的地球 RollEarth.java第34页/共37页Java的多线程机制35public class RollEarth extends Applet implements Runnable public void run()/实现动画 while(true)/循环往复地显示每一帧图片 try displayImage(m_Graphics);m_nCurrImage+;if(m_nCurrImage=NUM_IMAGES)m_nCurrImage=0;Thread.sleep(50);catch(InterruptedException e)/end of run()/end of class第35页/共37页Java的多线程机制36练习仿造TwoThreadsTest.java编制一个具有三个线程的ThreeThreadsTest.java。第36页/共37页Java的多线程机制37感谢您的观看!第37页/共37页