《java编程高级-多线程编程》由会员分享,可在线阅读,更多相关《java编程高级-多线程编程(31页珍藏版)》请在金锄头文库上搜索。
1、3 Sept. 2008 Neusoft ConfidentialJAVA编程高级 多线程编程多线程编程目标: Java线程机制以及多线程编程的实现 本章旨在向学员介绍: 1)Java线程模型。 2)Java多线程实现的两种方式:接口 和继承。 3)线程的休眠,中断及优先级。 4)线程的同步和死锁教学方法:讲授ppt 上机练习本章要点多线程简介多线程模型多线程实现的两种方式实现Runnable接口继承Thread类线程的属性和控制线程状态及其生命周期线程类的主要方法休眠和中断多线程同步/通信问题线程同步,锁和死锁多线程简介1多线程实现的两种方式2线程的属性和控制3多线程同步/通信问题4Cont
2、ents多线程简介进程 计算机在执行的程序 的实体e.g. 一个.class文件一个.exe文件线程 一个程序内部 的顺序控制流一个进程中可以包含 一个或多个线程,一个 线程就是一个程序内部 的一条执行线索 基本概念 进程/线程区别 进程和线程的区别 多进程和多线程 示例 HostAParty.java 每个进程都有独立的代码和数据空间,进程的切换 会有很大的开销 同一类线程共享代码和数据空间,每个线程有独立 运行的栈和程序计数器,线程切换的开销小 多进程:在操作系统中能同时运行多个任务(程序) 多线程:在同一应用程序中有多个顺序流同时执行Contents多线程简介1多线程实现的两种方式2线程
3、的属性和控制3多线程同步/通信问题4多线程实现的两种方式多线程的实现(1) 创建线程类继承Thread类 或实现Runnable接口(2) 通过Thread类构造器来创建线程对象 Thread( ) Thread(Runnable target)(3) 通过start()方法激活线程对象线程运行多线程实现的两种方式创建线程的两种方式 线程类继承Thread类 java.lang.Thread实现Runnable接口 java.lang.Runnablerun( )方法 线程运行体要将一段代码(线程体)在一个新的线程上运行,该代码应该在一 个线程类的run( )函数中写一个类implements
4、 Runnable接口,且必须覆盖Runnable接口 中的run( )方法写一个类extends Thread类,且必须重写Thread类的run( )方法继承Thread类实现线程类线程类线程调用 定义线程类继承 Thread类 覆盖run( )方法public void run( ) 继承Thread类ThreadDemo.javaTestThread.java继承Thread类实现线程类run( ) 与 start( )TestThread.java实现Runnable接口实现线程类线程类线程调用 定义线程类实现 Runnable接口 线程共享同样 的 数据和代码 覆盖Runnable
5、接口中的唯一的方法public void run( ) 实现Runnable接口RunnableDemo.javaTestRunnable.java两种实现方式的比较两种方式的比较使用Runnable接口可以避免由于JAVA的单继承性带来的局限适合多个相同的程序代码的线程去处理同一资源情况,把线程同 程序的代码、数据有效的分离推荐使用实现Runnable接口示例TicketRunnable.javaTicketThread.javaTestTicket.javaContents多线程简介1多线程实现的两种方式2线程的属性和控制3多线程同步/通信问题4线程状态及其生命周期线程的状态及其生命周期一
6、个 Thread 对象在它的整个生存期中能以几种不同的状态存在start( ) 方法使线程处于可以运行的状态,但不一定意味着该线程立即开始运行线程类中的主要方法线程中的主要方法 java.lang.Thread线程的优先级线程的优先级Java提供一个线程调度器来监控程序中启动后进入就绪状态的所用线程,线程调度器按照线程的优先级来决定应调度哪个线程来 执行线程的优先级用数字表示,范围从1到10,一个线程缺省的优先级是5Thread.MIN_PRIORITY = 1Thread.NORM_PRIORITY = 5Thread.MAX_PRIORITY = 10线程优先级方法getPriority(
7、 ) 确定线程的优先级setPriority( ) 设置线程的优先级T1.javaT2.javaTestPriority.java示例线程的休眠线程的休眠sleep( ) 让线程中止一段时间的静态方法 Thread.sleep(long millis) 暂时停止执行millis毫秒 在睡眠期满的瞬间,再次调用该线程不一定会恢复它的执行 join()join() 导致当前线程等待,直到调用这个 join 方法的线程终止 join( ) join(long millis) join(long millis,int nanos)yield()yield() 为其他可运行的线程提供执行机会 静态方法
8、Thread.yield( )Joining.javaTestJoin.javaYieldThread.javaTestYield.javasleeping.javaTestSleep.java线程的中断线程的终止自动终止 一个线程完成执行后,不能再次运行 手动终止 stop( ) 已过时,基本不用 interrupt( ) 粗暴的终止方式 可通过使用一个标志指示 run 方法退出,从而终止线程 推荐使用线程的高级操作线程的高级操作Object类中线程的相关方法:void wait() p导致当前的线程等待,直到其他线程调用此对象的 notify()方法或 notifyAll() 方法。voi
9、d notify() p唤醒在此对象监视器上等待的单个线程。void notifyAll() p唤醒在此对象监视器上等待的所有线程。Contents多线程简介1多线程实现的两种方式2线程的属性和控制3多线程同步通信问题4 同一票号被打印两次 打印出0,甚至负数票号线程同步售票程序 线程安全Ticket.javaTestSyn.java 解决方案 线程同步线程同步有时两个或多个线程可能会试图同时访问一个资源例如,一个线程可能尝试从一个文件中读取数据,而另一个线程 则尝试在同一文件中修改数据在此情况下,数据可能会变得不一致为了确保在任何时间点一个共享的资源只被一个线程使用,使 用了“同步”当一个线
10、程运行到需要同步的语句后,CPU不去执行其他线程中 的、可能影响当前线程中的下一句代码的执行结果的代码块,必 须等到下一句执行完后才能去执行其他线程中的相关代码块,这 就是线程同步synchronized (Object) /要同步的语句锁synchronized void methodA() 锁定方法 锁定代码块 实现同步的两种方式 一旦一个包含锁定方法(用synchronized修饰)的线程被CPU调用,其 他线程就无法调用相同对象的锁定方法。当一个线程在一个锁定方法内部, 所有试图调用该方法的同实例的其他线程必须等待要取得 锁的对 象锁实现同步的两种方式 锁定方法使用同步方 法未使用同
11、步锁实现同步的两种方式锁定代码块使用同步 代码块锁实现同步的两种方式注意事项:受到synchronized保护的程序代码块和方法中,要访问的对 象属性必须设定为private,因为如果不设定为private,那么就可以用不同的方式来访问它,这样就达不到保护的效果了示例: Syn.java锁 优点: 可以显示的知道哪些方法是 被锁定的 缺点: 方法中有些程序时不需要保 护的,如果该方法执行会花很 长时间,那么其他人就要花较 多时间等待锁被归还; 只能取得自己对象的锁,有时 候程序设计的需求,可能会需 要取得其他对象的锁;锁定代码块 实现同步的两种方式两种方式的优缺点锁定方法 优点: 可以针对某段程序代码锁定 ,不需要浪费时间在别的 程序代码上; 可以取得不同对象的锁; 缺点: 无法显示的得知哪些方法 是被锁定的;死锁死锁乱用synchronized可能会造成系统打死锁(Dead Lock)的状况!锁的归还几种方式:基本上执行完锁定的程序代码后,锁就会自动归还;用break语句跳出锁定的语句块,不过这对于写在方法声明 的synchronized没有作用;遇到return语句;遇到了异常;本章小结多线程简介多线程模型多线程实现的两种方式实现Runnable接口继承Thread类线程的属性和控制线程状态及其生命周期线程类的主要方法休眠和中断多线程同步/通信问题线程同步,锁和死锁