chap11多线程_第1页
chap11多线程_第2页
chap11多线程_第3页
chap11多线程_第4页
chap11多线程_第5页
已阅读5页,还剩47页未读 继续免费阅读

下载本文档

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

文档简介

1、1第第11章章 多线程多线程 本章主要讲述如下内容:本章主要讲述如下内容: 多线程的概念;多线程的概念; 线程的生命周期;线程的生命周期; 多线程编程中的常量和方法;多线程编程中的常量和方法; 线程调度方法;线程调度方法; 资源冲突与协调;资源冲突与协调; 线程之间的通信。线程之间的通信。 211.1 Java中多线程的基本概念中多线程的基本概念 在多线程模型中,多个线程共存于同一块在多线程模型中,多个线程共存于同一块内存中,且共享资源。内存中,且共享资源。 每个线程分配有限的时间片来处理任务。每个线程分配有限的时间片来处理任务。由于由于CPU在各个线程之间的切换速度非常在各个线程之间的切换速

2、度非常快,用户感觉不到,从而认为并行运行。快,用户感觉不到,从而认为并行运行。 311.1.1 多线程的特点多线程的特点 多个线程在运行时,系统自动在线程之间多个线程在运行时,系统自动在线程之间进行切换;进行切换; 由于多个线程共存于同一块内存,线程之由于多个线程共存于同一块内存,线程之间的通信非常容易;间的通信非常容易; Java将线程视为一个对象。线程要么是将线程视为一个对象。线程要么是Thread类的对象,要么是接口类的对象,要么是接口Runnable的的对象。对象。411.1.1 多线程的特点多线程的特点(续续) 当多个线程并行执行时,具有较高优先级当多个线程并行执行时,具有较高优先级

3、的线程将获得较多的的线程将获得较多的CPU时间片;时间片; 优先级是从优先级是从0到到10的整数,并且它仅表示的整数,并且它仅表示线程之间的相对关系;线程之间的相对关系; 多个线程共享一组资源,有可能在运行时多个线程共享一组资源,有可能在运行时产生冲突。必须采用产生冲突。必须采用synchronized关键字关键字协调资源,实现线程同步。协调资源,实现线程同步。59.2.1 多线程编程中常用的常量和方法多线程编程中常用的常量和方法 线程类线程类Thread定义在定义在java.lang包中;包中; Thread类包含的常量有:类包含的常量有:1. public static final int

4、 MAX_PRIORITY: 最大优先级,值是最大优先级,值是10。2. public static final int MIN_PRIORITY: 最小优先级,值是最小优先级,值是1。3. public static final int NORM_PRIORITY:缺省优先级,值是缺省优先级,值是5。 优先级的定义有部分在不同系统间有差别优先级的定义有部分在不同系统间有差别。 不要假定高优先级的线程一定先于低优先不要假定高优先级的线程一定先于低优先级的线程执行,不要有逻辑依赖于线程优级的线程执行,不要有逻辑依赖于线程优先级,否则可能产生意外结果先级,否则可能产生意外结果6711.2.1 多线

5、程编程中常用的常量和方法多线程编程中常用的常量和方法(续续) 常用方法:常用方法:currentThread( ):返回当前运行的线程对象,是返回当前运行的线程对象,是一个静态的方法。一个静态的方法。sleep(int n):使当前运行的线程睡使当前运行的线程睡n个毫秒,然后个毫秒,然后继续执行,也是静态方法。继续执行,也是静态方法。yield( ):使当前运行的线程放弃执行,切换到其使当前运行的线程放弃执行,切换到其它线程,是一个静态方法。它线程,是一个静态方法。isAlive( ):判断线程是否处于执行的状态,返回判断线程是否处于执行的状态,返回值值true表示处于运行状态,表示处于运行状

6、态,false表示已停止。表示已停止。89.2.1 多线程编程中常用的常量和方法多线程编程中常用的常量和方法(续续)start( ):使调用该方法的线程开始执行。使调用该方法的线程开始执行。run( ):该方法由该方法由start( )方法自动调用。方法自动调用。stop( ):使线程停止执行,并退出可执行状态。使线程停止执行,并退出可执行状态。suspend():使线程暂停执行,不退出可执行态。使线程暂停执行,不退出可执行态。resume( ):将暂停的线程继续执行。将暂停的线程继续执行。setName(String s):赋予线程一个名字。赋予线程一个名字。getName( ):获得调用线

7、程的名字。获得调用线程的名字。911.2.1 多线程编程中常用的常量和方法多线程编程中常用的常量和方法(续续)getPriority( ):获得调用线程的优先级。获得调用线程的优先级。setPriority(int p):设置线程的优先级。设置线程的优先级。join( ):等待线程死亡,若中断了该线程,等待线程死亡,若中断了该线程, 将抛出异常。将抛出异常。1011.2.1 多线程编程中常用的常量和方法多线程编程中常用的常量和方法(续续) 注意注意1 1:在创建线程对象时,缺省的线程优:在创建线程对象时,缺省的线程优先级是先级是5,一般设置优先级,一般设置优先级4到到6之间,不要之间,不要设置

8、为设置为10,否则其它线程将执行不到。,否则其它线程将执行不到。 注意注意2 2:Java的调度器能使高优先级的线程的调度器能使高优先级的线程始终运行,一旦始终运行,一旦CPUCPU有空闲,具有同等优先有空闲,具有同等优先级的线程,以轮流的方式顺序使用时间片。级的线程,以轮流的方式顺序使用时间片。 1111.2.2 线程的生命周期线程的生命周期 resume suspend wait stop I/O 请求结束 start notify notifyAll I/O 请求 睡眠时间结束 sleep 分配时间片 时间片结束 创建 就绪 运行 结束 挂起 阻塞 睡眠 等待 class getThre

9、adInfo / 程序程序1:单线程示例:单线程示例 public static void main(String args ) String name; int p;Thread curr; curr=Thread.currentThread( ); System.out.println(当前线程当前线程: +curr);name=curr.getName( );p=curr.getPriority( );System.out.println(线程名线程名: +name);System.out.println(优先级优先级 :+p); 程序输出结果:程序输出结果:当前线程当前线程: Thre

10、admain,5,main线程名线程名 : main优先级优先级 :5 1411.2.3 创建多线程的方法创建多线程的方法 方法方法1 1:通过:通过Thread类的子类实现多线程。类的子类实现多线程。 方法方法2 2:定义一个实现:定义一个实现Runnable接口的类接口的类实现多线程。实现多线程。 1511.2.3 创建多线程的方法创建多线程的方法( (续续) ) 方法方法1 1:通过创建:通过创建Thread类的子类实现多类的子类实现多线程,步骤如下线程,步骤如下 :1. 定义定义Thread类的一个子类。类的一个子类。2. 定义子类中的方法定义子类中的方法run( ),覆盖父类中的覆盖

11、父类中的 方法方法run( )。3. 创建该子类的一个线程对象。创建该子类的一个线程对象。4. 通过通过start( )方法启动线程。例如:方法启动线程。例如:/ 程序程序2class UserThread extends Thread int sleepTime; public UserThread(String id) / 构造方法构造方法super(id);sleepTime=(int)(Math.random( )*1000);System.out.println(线程名:线程名: +getName( )+,睡眠:睡眠: +sleepTime+ 毫秒毫秒); public void r

12、un( ) try / 通过线程睡眠模拟程序的执行通过线程睡眠模拟程序的执行 Thread.sleep(sleepTime); catch(InterruptedException e) System.err.println(运行异常运行异常: +e.toString( );System.out.println(运行的线程是:运行的线程是:+getName( );public class multThreadTestpublic static void main(String args ) UserThreadt1,t2,t3,t4;t1=new UserThread(NO 1);t2=new

13、 UserThread(NO 2);t3=new UserThread(NO 3);t4=new UserThread(NO 4); t1.start( );t2.start( );t3.start( );t4.start( );程序某次的运行结果:程序某次的运行结果:线程名:线程名: NO 1,睡眠:睡眠: 885 毫秒毫秒线程名:线程名: NO 2,睡眠:睡眠: 66 毫秒毫秒线程名:线程名: NO 3,睡眠:睡眠: 203 毫秒毫秒线程名:线程名: NO 4,睡眠:睡眠: 294 毫秒毫秒目前运行的线程是:目前运行的线程是:NO 2目前运行的线程是:目前运行的线程是:NO 3目前运行的线

14、程是:目前运行的线程是:NO 4目前运行的线程是:目前运行的线程是:NO 1 注意:注意:Thread类中的类中的run( )方法具有方法具有public属属性,覆盖该方法时,前面必须带上性,覆盖该方法时,前面必须带上public。 2011.2.3 创建多线程的方法创建多线程的方法( (续续) ) 方法方法2 2:通过接口创建多线程,步骤如下:通过接口创建多线程,步骤如下: 1.定义一个实现定义一个实现Runnable接口的类。接口的类。 2.定义方法定义方法run( )。Runnable接口中有一个空接口中有一个空的方法的方法run( ),实现它的类必须覆盖此方法。实现它的类必须覆盖此方法

15、。 3.创建该类的一个线程对象,并将该对象作参创建该类的一个线程对象,并将该对象作参数,传递给数,传递给Thread类的构造函数,从而生成类的构造函数,从而生成Thread类的一个对象。类的一个对象。 / 注意这一步注意这一步!4.通过通过start( )方法启动线程。例如方法启动线程。例如3:/ 程序程序3class UserMultThread implements Runnableint num;UserMultThread(int n) num=n;public void run( ) for(int i=0;i3;i+) System.out.println(运行线程:运行线程:+n

16、um); System.out.println(结束结束 : +num);public class multThreadZero public static void main(String args ) throws InterruptedException Thread mt1=new Thread(new UserMultThread(1);Thread mt2=new Thread(new UserMultThread(2);mt1.start( );mt2.start( );mt1.join( ); / 等待线程死亡等待线程死亡mt2.join( ); 程序运行某次的输出结果:程序运

17、行某次的输出结果:运行线程:运行线程:1运行线程:运行线程:2运行线程:运行线程:1运行线程:运行线程:2运行线程:运行线程:1运行线程:运行线程:2结束结束 : 1结束结束 : 22411.2.3 创建多线程的方法创建多线程的方法( (续续) ) 程序程序3中需要注意的中需要注意的2点:点:1. mt1.join( )是等待线程死亡,对该方法必是等待线程死亡,对该方法必须捕捉异常,或通过须捕捉异常,或通过throws关键字指明可关键字指明可能要发生的异常。能要发生的异常。 2. 对一个线程不能调用对一个线程不能调用start( )两次,否则会两次,否则会产生产生IllegalThreadSt

18、ateException异常异常。 2511.3.1 线程调度模型线程调度模型 线程调度程序挑选线程时,将选择处于就线程调度程序挑选线程时,将选择处于就绪状态且优先级最高的线程。绪状态且优先级最高的线程。 如果多个线程具有相同的优先级,它们将如果多个线程具有相同的优先级,它们将被轮流调度。被轮流调度。 程序程序4验证了验证了Java对多线程的调度方法。对多线程的调度方法。 class threadTest extends Thread / 程序程序4threadTest(String str) super(str); public void run( )tryThread.sleep(2);c

19、atch(InterruptedException e) System.err.println(e.toString( );System.out.println(getName( )+ + getPriority( );public class multTheadOnepublic static void main(String agrs)Thread one=new threadTest(one );Thread two=new threadTest(two );Thread three=new threadTest(three );one.setPriority(Thread.MIN_PR

20、IORITY);two.setPriority(Thread.NORM_PRIORITY);three.setPriority(Thread.MAX_PRIORITY);one.start( );two.start( );three.start( );程序输出结果:程序输出结果:three 10two 5one 12911.3.2 资源冲突资源冲突 多个线程同时运行虽然可以提高程序的执多个线程同时运行虽然可以提高程序的执行效率,但由于共享一组资源,可能会产行效率,但由于共享一组资源,可能会产生冲突,例如程序生冲突,例如程序5 5 。class UserThread / 程序程序5 void P

21、lay(int n) System.out.println(运行线程运行线程 NO:+n);tryThread.sleep(3);catch(InterruptedException e) System.out.println(“线程异常线程异常, NO:+n);System.out.println(结束线程结束线程 NO:+n);class UserMultThread implements Runnable UserThread UserObj;int num;UserMultThread(UserThread o,int n) UserObj=o;num=n;public void ru

22、n( ) UserObj.Play(num);public class multTheadTwo public static void main(String args ) UserThread Obj=new UserThread( );Thread t1=new Thread(new UserMultThread(Obj,1);Thread t2=new Thread(new UserMultThread(Obj,2);Thread t3=new Thread(new UserMultThread(Obj,3);t1.start( );t2.start( );t3.start( );程序输

23、出结果:程序输出结果:运行线程运行线程 NO:1运行线程运行线程 NO:3结束线程结束线程 NO:1结束线程结束线程 NO:3运行线程运行线程 NO:2结束线程结束线程 NO:23411.3.3 同步方法同步方法 Java通过关键字通过关键字synchronized实现同步。实现同步。 当对一个对象当对一个对象( (含方法含方法) )使用使用synchronized,这个对象便被锁定或者说进入了监视器这个对象便被锁定或者说进入了监视器。在一个时刻只能有一个线程可以访问被锁在一个时刻只能有一个线程可以访问被锁定的对象。它访问结束时,让高优先级并定的对象。它访问结束时,让高优先级并处于就绪状态的线

24、程,继续访问被锁定的处于就绪状态的线程,继续访问被锁定的对象对象,从而实现资源同步。从而实现资源同步。 加锁的方法有两种:锁定冲突的对象,或加锁的方法有两种:锁定冲突的对象,或锁定冲突的方法。锁定冲突的方法。 3511.3.3 同步方法同步方法( (续续) )1. 锁定冲突的对象锁定冲突的对象。语法格式:。语法格式:synchronized ( ObjRef ) Block / 需要同步执行的语句体需要同步执行的语句体 锁定对象可以出现在任何一个方法中。例如,锁定对象可以出现在任何一个方法中。例如,修改程序修改程序5中的方法中的方法run( ) 如下:如下: public void run(

25、) synchronized(UserObj) UserObj.Play(num); 运行结果如下:运行结果如下:运行线程运行线程 NO:1结束线程结束线程 NO:1运行线程运行线程 NO:2结束线程结束线程 NO:2运行线程运行线程 NO:3结束线程结束线程 NO:3 3711.3.3 同步方法同步方法( (续续) )2. 锁定冲突的方法锁定冲突的方法。语法格式:。语法格式:synchronized 方法的定义方法的定义 例如,修改程序例如,修改程序9-5中的方法中的方法Play( ) 如下:如下: synchronized void Play(int n) / 中间的程序代码略中间的程序代

26、码略 注意:注意:1. 对方法对方法run( )无法加锁,不可避免冲突;无法加锁,不可避免冲突; 2. 对构造函数不能加锁,否则出现语法错误。对构造函数不能加锁,否则出现语法错误。 3811.4 线程间通信线程间通信 多线程通信的方法有两种:多线程通信的方法有两种:1. 把共享变量和方法封装在一个类中实现;把共享变量和方法封装在一个类中实现;2. 通过通过wait( )和和notify( )方法实现。方法实现。 3911.4.1 通过封装共享变量实现线程通通过封装共享变量实现线程通信信 程序程序6演示了通过将共享变量封装在一个演示了通过将共享变量封装在一个类中,实现线程通信类中,实现线程通信c

27、lass comm /共享类共享类private int n;private boolean bool=false;void produce(int i) while(bool) n=i;bool=true;System.out.println(n 产生数据:产生数据:+n);void readout( ) while(!bool) bool=false;System.out.println( 读取数据:读取数据:+n); / 读取数据类读取数据类class dataProducer implements Runnablecomm cm;dataProducer(comm c) cm=c;pu

28、blic void run( ) / 生产者产生生产者产生5个随机数个随机数for(int i=0;i5;i+)duce(int)(Math.random( )*100);class dataConsumer implements Runnablecomm cm;dataConsumer(comm c) cm=c;public void run( ) for(int i=0;i5;i+) cm.readout( ); / 消费者读取数据消费者读取数据public class multTheadThree public static void main(String args ) c

29、omm cm=new comm( );Thread t1=new Thread( /无名对象做参数无名对象做参数new dataProducer(cm);Thread t2=new Thread(new dataConsumer(cm);t1.start( );t2.start( ); 程序的某次运行结果:程序的某次运行结果:产生数据:产生数据:81读取数据:读取数据:81 产生数据:产生数据:15读取数据:读取数据:15 产生数据:产生数据:92读取数据:读取数据:92 产生数据:产生数据:98读取数据:读取数据:98 产生数据:产生数据:79读取数据:读取数据:79 4511.4.2 通过

30、系统方法实现线程通信通过系统方法实现线程通信 线程同步控制的第二种方法是采用如下几线程同步控制的第二种方法是采用如下几个系统方法:个系统方法:1.wait( )方法:使一个线程进入等待状态,方法:使一个线程进入等待状态,直到被唤醒。直到被唤醒。 2.notify( )方法:通知等待监视器的线程,该方法:通知等待监视器的线程,该对象的状态已经发生了改变。对象的状态已经发生了改变。 3. notifyAll( )方法:唤醒从同一个监视器中方法:唤醒从同一个监视器中用用wait( )方法退出的所有线程,使它们按方法退出的所有线程,使它们按照优先级的顺序重新排队。例如照优先级的顺序重新排队。例如程序程

31、序7。 class comm / 程序程序7 private int n; private boolean bool=false; synchronized void produce(int i) if(bool) trywait( );catch(InterruptedException e) System.out.println(comm 出现异常出现异常);elsen=i;bool=true;System.out.println(n产生数据:产生数据: +n);notify( ); / 唤醒另外一个线程唤醒另外一个线程 synchronized void readout( ) if(!bool) trywait( );catch(InterruptedException e) System.out.println( comm 出现异常出现异常);elsebool=false;System.out.println(读取数据:读取数据: +n);notify( ); / 唤醒另一个线程唤醒另一个线程 class dataProducer implements Runnable comm cm;dataProducer (com

温馨提示

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

评论

0/150

提交评论