面向对象编程导论第八章.ppt

上传人:牧羊曲112 文档编号:5010067 上传时间:2023-05-29 格式:PPT 页数:32 大小:280.50KB
返回 下载 相关 举报
面向对象编程导论第八章.ppt_第1页
第1页 / 共32页
面向对象编程导论第八章.ppt_第2页
第2页 / 共32页
面向对象编程导论第八章.ppt_第3页
第3页 / 共32页
面向对象编程导论第八章.ppt_第4页
第4页 / 共32页
面向对象编程导论第八章.ppt_第5页
第5页 / 共32页
点击查看更多>>
资源描述

《面向对象编程导论第八章.ppt》由会员分享,可在线阅读,更多相关《面向对象编程导论第八章.ppt(32页珍藏版)》请在三一办公上搜索。

1、面向对象编程导论,授课人:宋东峰,第八章 线程,本讲概要,本讲重点,线程的概念线程的生命周期Java中多线程的编程继承Thread类与使用Runnable接口Thread类的主要方法线程的同步与死锁,4.1 线程及相关概念,程序:计算机高级语言编写的代码,静态,是应用程序的蓝本。进程:是程序的一次动态执行过程,进程包括所要执行的指令和所需的系统资源,不同的进程所占用的系统资源相对独立。线程:比进程更小的执行单位,自身不能自动运行,必须栖身于某一进程之中,由该进程触发执行,属于同一进程的线程共享该进程的系统资源。多进程:系统中多个程序同时执行(多任务)。多线程:程序(进程)中多个片断同时执行。,

2、4.1.1 线程及相关概念,Java程序执行的过程 当JVM加载代码,发现main方法之后,就会启动一个线程,这个线程称作“主线程”,该线程负责执行main方法。如果main方法中没有创建其他的线程,那么当main方法执行完最后一个语句,JVM就会结束Java应用程序。如果main方法中创建了其他线程,那么JVM就要保证每个线程都有机会使用CPU资源。JVM一直要等到主线程中的所有线程都结束之后,才结束Java应用程序。,4.1.2 线程的生命周期,线程的五个生命周期 新建:新建的线程处于新建状态。就绪:在创建线程后,它将处于就绪状态,排队等待进程调用。运行:线程获得CPU资源后,就进入运行状

3、态,开始执行。阻塞:在线程等待一个事件时(例如输入/输出操作),就处于阻塞状态。死亡:线程不再具有继续运行的能力。线程完成了自己的任务。线程被强迫终止。,4.1.2 线程生命周期示意图,4.2 基本编程思路,例: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();/main方法所在线程的执行代码,4.2 线程的优先级和调度调度,当一个在就绪队列中排

4、队的线程被分配到处理器资源而进入运行状态之后,这个线程就称为被“调度”或被线程调度管理器选中了。线程调度管理器负责管理线程排队和处理器在线程之间的分配 在java系统中,线程调度依据优先级基础上的“先到先服务”原则。,线程的优先级和调度调度,Java虚拟机(JVM)中的线程调度器负责管理线程,调度器把线程的优先级分为10个级别。优先级使用Thread类中的类常量表示。,static int MIN_PRIORITY 值为1static int MAX_PRIORITY 值为10static int NORM_PRIORITY 值为5,int getPriority():返回线程的优先级。voi

5、d setPriority(int a)可以设置线程优先级。,4.2.2 线程的创建,创建线程有两种方法继承Thread类实现Runable接口,每个Java程序至少有一个叫做主线程的线程 Thread类的currentThread方法可以获取主线程(或当前线程)。getName方法可以取得主线程(或当前线程)的名字。setName方法可以设置线程的名字。,4.2.3 线程的创建,public class mainthread public static void main(String args)Thread thread=Thread.currentThread();System.out.

6、println(thread.getName();thread.setName(“main thread”);System.out.println(thread.getName();,mainmain thread,4.3线程的创建,继承Thread类 常用构造方法:public Thread()public Thread(String name)public Thread(Runnable target),Thread thread1=new Thread();Thread thread2=new Thread(“second”);,class TestThread extends Thre

7、adpublic TestThread(String name)super(name);,TestThread thread1=new TestThread(“second”);,4.3 线程的创建,Thread类的常用方法 public void start()调用该方法启动线程,使线程从新建状态转入就绪状态并进入就绪队列。public void run()Thread类中run()方法体为空,编写Thread类的子类时,需要在子类中覆盖父类的run()方法,该方法中包含了对线程的操作。,class mythread extends Thread public void run()/*覆盖该

8、方法*/,4.3 线程的创建,需要注意的问题 程序需要建立自己的线程时,只需要创建一个已定义好的Thread子类的实例就行了。当创建的线程调用start()方法开始运行时,run()方法将被自动执行。当run()方法执行完毕,线程就释放内存。在线程没有结束run()方法前,不赞成让线程再调用start()方法,否则将发生IllegalThreadStateException异常,4.3 线程的创建,public static void sleep(long millis)优先级高的线程在它的run()方法中调用sleep方法来使自己放弃处理器资源,休眠一段时间。public final boo

9、lean isAlive()检查线程是否仍然在运行。Static Thread currentThread()判断当前正在占有CPU的线程。Join()守护线程的使用,public class LeftAndRightpublic static void main(String args)Lefthand left;Righthand right;left=new Lefthand();/创建线程 right=new Righthand();left.start();/线程开始运行后,Lefthand类中run方法被执行 right.start();/线程开始运行后,Righthand类中ru

10、n方法被执行,class Righthand extends Thread public void run()for(int i=1;i=5;i+)System.out.print(“B”);trysleep(300);catch(InterruptedException e),运行结果:ABBABBABAA,class Lefthand extends Thread public void run()for(int i=1;i=5;i+)System.out.printl(“A”);try sleep(500);catch(InterruptedException e),4.3 实现Runn

11、able接口,实现Runnable接口 Runnabale接口只有一个方法run(),所有实现Runnable接口的类都必须具体实现run()方法,定义具体操作。,class mythread implements Runnable public void run()/*实现该方法*/,一个实现了Runnable接口的类实际上定义了一个主线程外的新线程的操作。,4.3 实现Runnable接口,public Thread(Runnable target)public Thread(Runnable target,String name)使用Runnable对象创建一个线程对象。参数target

12、称为被创建线程的目标对象,创建目标对象的类负责实现Runable接口。,class runnable implements Runnable public runnable()Thread thread=new Thread(this,second);public void(),4.3 线程的基本控制,检查线程 使用isAlive()方法检查线程是否在活动状态。活动状态说明这个线程已经被启动,并不一定正在执行。,挂起线程 使用sleep()来延迟线程的执行。通常,线程不是休眠期满后就立即被唤醒(start),重新调度的情况是:被唤醒的线程具有更高的优先级。正在执行的线程因为其他原因被阻塞。程序

13、处于支持时间片的系统中。,4.3 线程的基本控制,结束线程 自然结束:从run()结尾返回 public void interrupt(),当线程阻塞时,会抛出InterruptedException异常,所以往往需要调用public void isInterrupted()方法来判断线程的阻塞状态,不推荐使用的方法 public final void stop()public final void suspend()public final void resume(),4.4 数据的完整性,4.4 数据的完整性,对共享对象的访问必须同步,叫做条件变量.Java语言允许通过监视器(有的参考书称

14、其为管程)使用条件变量实现线程同步.监视器阻止两个线程同时访问同一个条件变量.它的如同锁一样作用在数据上.线程1进入withdrawal方法时,获得监视器(加锁);当线程1的方法执行完毕返回时,释放监视器(开锁),线程2的withdrawal方能进入.,4.4 数据的完整性,用synchronized来标识的区域或方法即为监视器监视的部分。一个类或一个对象由一个监视器,如果一个程序内有两个方法使用synchronized标志,则他们在一个监视器管理之下.一般情况下,只在方法的层次上使用关键区,4.4 多线程问题-资源协调,此处给出的例子演示两个线程在同步限制下工作的情况.class Accou

15、nt statics int balance=1000;/为什么用static?statics int expense=0;public synchronized void withdrawl(int amount)if(amount=balance)balance-=amount;expense+=amount;else System.out.println(“bounced:“+amount);,4.5 线程同步,当两个或多个线程同时访问同一个对象,且其中一个线程要修改这个对象,这时可能产生混乱,这就是典型的同步问题。,对象的锁定标志 Java可以为每一个对象的实例分配一个标志,称为锁定标

16、志,用来处理同步问题。每个线程通过排队等待的方式获得这个锁定标志来独享对象。synchronized提供了操作这个标志的方法。当持有锁定标志的线程运行完synchronized调用包含的语句后,这个标志会被自动返回,4.5 线程同步,同步方法 synchronized()标准写法:public void test()synchronized(this).简洁写法:public synchronized test().,例:会计和出纳共同拥有一个账本,他俩都可以使用存取方法对账本进行访问,但不能同时对账本的账目进行访问,4.5 多线程问题-资源协调,多线成问题-资源的协调和锁定死锁问题如果你的持

17、有一个锁并试图获取另一个锁时,就有死锁的危险.解决死锁问题的方法:给条件变量施加排序,4.5 多线程问题-资源协调,可能出现的问题:生产者比消费者快时,消费者会漏掉一些数据没有取到消费者比生产者快时,消费者取相同的数据.notify()和wait()方法用来协调读取的关系.notify()和wait()都只能从同步方法中的调用.,4.5 多线程问题-资源协调,使用wait()、notify()和notifyAll()进行线程间的交互 这种交互是通过队列来实现的。wait()、notify()和notifyAll()都是Object类中的final方法,被所有的类继承,且不允许重写的方法。,pu

18、blic final void wait()当一个线程使用的同步方法中用到某个变量,而此变量又需要其他线程修改后才能符合本线程的需要,那么可以在同步方法中使用wait()方法。使用wait()方法可以中断方法的执行,使本线程等待,暂时让出CPU的使用权,并允许其他线程使用这个同步方法。,4.5 多线程问题-资源协调,public final void notifyAll()其它线程如果在使用这个同步方法时不需要等待,那么它使用完这个同步方的同时,应当用notifyAll()方法通知所有的由于使用这个同步方法处于等待的线程结束等待,曾被中断的线程就会从刚才的中断处继续执行这个同步方法,并遵循“先中断线继续”的原则。public final void notify()只是通知第一个处于等待状态的线程结束等待,并唤醒它。,例:模拟两个人排队买票,张某、李某买电影票,售票员只有两张5元的钱,电影票5元一张。张某拿一张20元排在李的前面,李某排拿一张5元买票。,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号