Ch10 多线程v2_第1页
Ch10 多线程v2_第2页
Ch10 多线程v2_第3页
Ch10 多线程v2_第4页
Ch10 多线程v2_第5页
已阅读5页,还剩40页未读 继续免费阅读

下载本文档

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

文档简介

1、 第 10 章 多 线 程1教学目标10.1线程的概念10.2线程的创建和执行 10.2.1 Thread类和Runnable接口介绍 10.2.2通过继承Thread的子类创建线程 10.2.2 通过实现Runnable 接口创建线程10.3 线程的状态与生命周期10.4 线程优先级与线程的控制教学目标10.5 线程同步 11.5.1 Synchonized同步关键字 11.5.2 Wait和Notify方法 11.5.3多线程同步的程序设计举例10.6 死锁 10.7 小结10.1 线程的概念Java语言支持多线程机制可开发出处理多个任务的功能强大的应用程序。并行任务的应用举例1. 程序、

2、进程与线程的概念 程序是一段静态的代码 进程是程序一次动态执行的过程.它对应着从代码加载、执行到执行完毕的一个完整过程,这个过程也是进程本身从产生、发展到消亡的过程。进程是由操作系统来管理.多线程:当需要在一个程序中同时执行几段代码时,以完成不同的任务,就会用多线程技术来实现.多线程由程序负责管理。 10.1 线程的概念 线程是进程中可独立执行的子任务,一个进程可以含有一个或多个线程,每个线程都有一个唯一的标识符。进程和线程的区别:进程空间大体分为: 数据区,代码区,栈区,堆区。多个进程的内部数据和状态都是完全独立的;而线程共享进程的数据区,代码区,堆区,只有栈区是独立的,所以线程切换比进程切

3、换的代价小。 10.1 线程的概念 文件输入输出装置各种系统资源数据区段程序区段同时有数个地方在执行一个进程内的单线程一个进程内的多线程的任务文件输入输出装置各种系统资源数据区段程序区段只有一个地方在执行10.1 线程的概念 10.2线程的创建和执行Java的线程相关的类在软件包java.lang中。在程序中实现多线程有两种方式:1、通过继承Thread类的子类创建线程对象2、通过实现Runnable接口创建线程对象。这两种方式都要两个关键性的操作: (1)定义用户线程的操作,即实现线程的run( )方法的方法体; (2)构造Thread类对象,实现线程的建立和运行控制。 10.2.1 Thr

4、ead类和Runnable接口介绍 1Runnable接口介绍Runnable接口只有一个方法run( )所有实现Runnable接口的类必须实现这个方法。它定义了线程体的具体操作。当线程被调度并转入运行状态时,它所执行run( )方法中规定的操作。2Thread类介绍Thread类是一个具体的类,它封装了一个线程所需要的属性和方法。Thread类实现Runnable接口中的run方法, 但方法体为空。 10.2.1 Thread类和Runnable接口介绍3Thread类的构造方法Thread ( String threadName ) 为新创建的线程对象指定一个字符串名称threadNam

5、e。Thread ( ) 线程对象的名称由系统指定为“Thread-”连接一个数值。 如“Thread-1” 、“Thread-2”Thread ( Runnable target ) 以实现Runnable接口的target对象中所定义的run( )方法,来初始化或覆盖新创建的线程对象的run( )方法。10.2.2通过继承Thread的子类创建线程创建用户定制的Thread类的子类,并在子类中重新定义自己的run( )方法,这个run( )方法中包含了用户线程的操作。例10-1 通过定制的Thread的子类,创建多线程。 该程序是一个Application程序,主线程是main( )方法执

6、行的路线。在主线程中创建另一个线程,其名称是r。程序文件:TestThread1.java例10-1通过继承Thread类创建线程public class TestThread1 public static void main(String args) Runner1 r = new Runner1(); /创建线程对象r.start(); /启动该线程for(int i=0; i100; i+) System.out.println(Main Thread:- + i); class Runner1 extends Thread public void run() for(int i=0;

7、i100; i+) System.out.println(Runner1 : + i); 10.2.2通过继承Thread的子类创建线程例10-2 通过定制的Thread的子类,创建多线程。 该程序是一个Application程序,主线程是main( )方法执行的路线。在主线程中创建三个线程,其名称是thread1、thread2和thread3,每个线程的优先级均为默认的Thread.NORM_PRIORITY。每个线程启动后,由系统执行run()方法,运行将显示信息:进入睡眠的线程名称和要休眠的时间.。程序运行输出结果如图11-3 public class ThreadTester pub

8、lic static void main( String args ) / 创建和命名三个线程 PrintThread thread1 = new PrintThread( thread1 ); PrintThread thread2 = new PrintThread( thread2 ); PrintThread thread3 = new PrintThread( thread3 ); System.err.println( 主线程将要启动三个线程 ); thread1.start(); / 启动thread1,进入就绪状态 thread2.start(); /启动thread2,进入就

9、绪状态 thread3.start(); /启动thread3,进入就绪状态 System.err.println( 三个线程启动完成, 主线程运行结束n ); class PrintThread extends Thread private int sleepTime; public PrintThread( String name ) super( name ); / 通过调用父类构造方法给 thread 命名 sleepTime = ( int ) ( Math.random() * 5001 ); / 设置睡眠时间0到5 秒 public void run( ) / 设置线程运行的线程

10、体 try System.err.println( getName() + 进入睡眠状态,睡眠时间是: + sleepTime ); Thread.sleep( sleepTime ); catch ( InterruptedException exception ) System.err.println( getName() + 睡眠醒来 ); / 显示线程名称 10.2.2 实现Runnable 接口创建线程通过实现Runnable 接口创建线程的步骤:创建实现Runnable接口的类,在此类中实现Runnable接口中run()方法;创建此类的对象,并将此对象作为参数传递给 Thread

11、类的构造方法,构造Thread对象并启动它。只要一段代码在单独线程中运行,则可以继承Runnable接口,并将该段代码放在该接口run()方法中。例10-3: 实现Runnable 接口,创建线程public class TestRunnable public static void main(String args) Runner1 r = new Runner1(); /创建 Thread 时将r对象作为一个参数来传递并启动Thread t = new Thread( r ); t.start();for(int i=0; i100; i+) System.out.println(Main

12、 Thread:- + i); class Runner1 implements Runnable public void run() for(int i=0; i= amount ) balance -= amount; return true; else return false; public set(double amount) /存钱 balance+=amount; 线程 3存钱 线程1取钱线程2取钱透支余额class bank static double balance; synchonized public boolean get(double amount) /取钱 sync

13、honized public set(double amount) /存钱 10.5 线程同步10.5 线程同步在Java语言中,引入了“对象互斥锁”的概念(又称为监视器、管程)来实现不同线程对共享数据操作的同步。这个标记用来保证在任一时刻,只能有一个线程访问该对象。即,“对象互斥锁”阻止多个线程同时访问同一共享资源。在Java语言中,有两种方法可以实现“对象互斥锁”:(1)用关键字volatile来声明一个共享数据(变量);(2)用关键字synchronized来声明一个操作共享数据的方法或一段代码。一般情况下,都使用synchronized关键字在方法的层次上实现对共享资源操作的同步,很少

14、使用volatile关键字声明共享变量。10.5.1 Synchonized同步关键字 为了保证共享对象的正确性,Java语言中,使用关键字synchonized修饰对象的同步语句或同步方法。 synchonized的一般使用格式有: synchonized (对象) 或 synchonized 方法声明头 定义对象的同步代码块定义对象的同步方法一个对象上可定义多个同步语句或同步方法。 10.5.1 Synchonized同步关键字一个对象上可定义多个同步语句或同步方法。Java系统只允许一个线程,执行对象的一个同步语句或一个同步方法。一个线程在进入同步语句或同步方法时要给对象加互斥锁(获得锁

15、),一个对象只能加一把互斥锁,加锁成功时才能执行同步语句;而其它所有试图对同一个对象执行同步语句的线程,因加锁不成功都将处于阻塞状态。在同步语句或同步方法完成执行时,同步对象上的锁被解除,并让最高优先级的阻塞线程处理它的同步语句。一个对象中的所有synchronized方法都共享一把锁,这把锁能够防止多个方法对共用内存同时进行的写操作。10.5.2 多线程同步的程序设计举例一、同步化方法通过锁定方法实现同步化过程。例10-5:以生产者和消费者的关系模型。生产者线程消费者线程共享对象putget 若共享对象中只能存放一个数据,可能出现以下问题: 生产者比消费者快时,消费者会漏掉一些数据没有取到;

16、 消费者比生产者快时,消费者取相同的数据。10.5.2 多线程同步的程序设计举例生产者和消费者的关系模型,程序由四个类组成:Share共享资源类;Producer生产者类;Consumer消费者类;ProdConsModel公共类,在main方法中,创建了一个生产者线程和一个消费者线程,并分别启动了它们。程序代码: 书上P204例10.4,ProdConsModel.java文件10.5.2 多线程同步的程序设计举例二、同步化对象通过锁定对象的方式使线程同步。例10-6 共用公司银行账户模型(即书上P207例10.5 )。 设计了3个独立类:银行账户类、存款线程类、取款线程类。存款线程类为可执

17、行类。程序代码:Save.java10.5.3 Wait和Notify方法出于代码的安全性和健壮性的考虑,java放弃了使用原来的suspend、resume方法来处理线程的挂起等待和唤醒继续,取而代之则是从Object类继承而来的:wait( ) /这个方法可以使线程一直等待,直到其他线程调用notify(或notifyAll)将其唤醒。notify() /唤醒一个等待同一个管程锁的线程,如果同一管程锁下有多个线程处于睡眠等待状态,则随机地挑出一个等待线程将其唤醒。notifyAll() /唤醒所有等待同一管程锁的线程,这些唤醒后的线程同样也要拥有管程才能继续执行。这三个方法必须在synch

18、ronized代码块中调用,否则会出现IllegalMonitorStateException异常。注意:wait方法和notify方法一般配合使用。wait()和sleep()的区别:wait()方法被调用时会解除锁定,但使用它的地方只是在一个同步的方法或代码块内。10.6 死锁 多线程在使用互斥机制实现同步的同时不仅会带来阻塞,还会带来 “死锁” (deadlock)的潜在危险。 触发死锁的发生的例子:线程A锁住了线程B等待的资源,而且线程B锁住了线程A等待的资源,即线程B一直在等待线程A释放锁,线程A也是如此。如果你的持有一个锁并试图获取另一个锁时,就有死锁的危险。线程2pen线程1note把“pen”给我,我才能给你“note”把“note”给我,我才能给你“pen”10.6 死锁Java技术即不能发现死锁也不能避免死锁。程序员多线程编程时,应注意死锁问题,尽量避免。防止死锁的方法:对竞争的资源引入序号,如果一个线程需要几个资源,那么它必须先得到小序号的资源,再申请大序号的资源。在程序中不提倡使用线程的停止/销毁线程的方法stop()的/destroy(),挂起/恢复线程的方法su

温馨提示

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

评论

0/150

提交评论