1、Java程序设计程序设计第七章 多线程第第7章章多线程线程简介线程简介 ThreadThread类的子类创建线程类的子类创建线程 实现实现RunnableRunnable接口接口基本的线程控制基本的线程控制线程的调度线程的调度多线程的互斥与同步多线程的互斥与同步DaemonDaemon线程线程重点内容重点内容:如何定义一个线程如何定义一个线程线程的状态转换关系图线程的状态转换关系图线程间如何实现共享数据线程间如何实现共享数据线程间如何处理临界资源线程间如何处理临界资源线程间如何实现相互通信线程间如何实现相互通信理解生产者理解生产者-消费者模型消费者模型7.1 线程简介线程简介理解线程理解线程理
2、解多线程理解多线程7.1 线程简介线程简介 程程序序:是是一一段段静静态态的的代代码码,它它是是应应用用软软件件执执行的蓝本行的蓝本进进程程:是是程程序序的的一一次次动动态态执执行行过过程程,它它对对应应了了从从代代码码加加载载、执执行行至至执执行行完完毕毕的的一一个个完完整整过程过程线线程程:线线程程是是比比进进程程更更小小的的执执行行单单位位,一一个个进进程程在在执执行行过过程程中中,可可以以产产生生多多个个线线程程,形形成成多多条条执执行行线线索索。一一条条执执行行线线索索就就是是一一个个线线程程。每每个个线线程程都都有有各各自自独独立立的的运运行行栈栈和和程程序序计数器计数器7.1.1
3、进程与线程进程与线程多线程实现机制:多线程实现机制:CPU时间片在多个独时间片在多个独立的线程间切换,从宏观上看,在一个立的线程间切换,从宏观上看,在一个程序运行期间,有多个顺序流同时执行程序运行期间,有多个顺序流同时执行多线程代码和数据共享多线程代码和数据共享代码可以或不可以由多个线程共享。代码可以或不可以由多个线程共享。如果两个线程执行同一个类的实例代码,则如果两个线程执行同一个类的实例代码,则如果两个线程执行同一个类的实例代码,则如果两个线程执行同一个类的实例代码,则它们可以共享相同的代码。它们可以共享相同的代码。它们可以共享相同的代码。它们可以共享相同的代码。数据可以或不可以由多个线程
4、共享。数据可以或不可以由多个线程共享。如果两个线程共享对一个公共对象的存取,如果两个线程共享对一个公共对象的存取,如果两个线程共享对一个公共对象的存取,如果两个线程共享对一个公共对象的存取,则它们可以共享相同的数据。则它们可以共享相同的数据。则它们可以共享相同的数据。则它们可以共享相同的数据。7.1.2线程的状态线程的状态 线程在它的一个完整的生命周期中通常要经历如线程在它的一个完整的生命周期中通常要经历如线程在它的一个完整的生命周期中通常要经历如线程在它的一个完整的生命周期中通常要经历如下的几种状态:下的几种状态:下的几种状态:下的几种状态:1.1.创建创建创建创建 (new Thread)
5、(new Thread)2.2.可运行可运行可运行可运行(RunnableRunnable)3.3.运行运行运行运行(Running)(Running)4.4.阻塞(阻塞(阻塞(阻塞(Not Not RunnableRunnable)5.5.死亡(死亡(死亡(死亡(DeadDead)Start()Run()执行完执行完123定义线程的方法定义线程的方法1.实现实现Runnable接口接口 public class mythread implements Runnable 2.定义定义Thread类的子类类的子类 public class mythread extends Threadpubli
6、c void run()public void run():是线程运行的主体是线程运行的主体,当当JVMJVM将将CPUCPU使用权切换给线程,使用权切换给线程,启动线程时,启动线程时,runrun方法就立刻执行。方法就立刻执行。7.2 Thread类的子类创建线程类的子类创建线程编写编写Thread类的子类时,需要重写父类的类的子类时,需要重写父类的run方法,其目的是规定线程的具体操作,方法,其目的是规定线程的具体操作,否则线程就什么也不做,因为父类的否则线程就什么也不做,因为父类的run方法中没有任何操作语句。方法中没有任何操作语句。P170 例7-27.3 实现实现Runnable接口
7、接口 用用用用ThreadThread类直接创建线程对象类直接创建线程对象类直接创建线程对象类直接创建线程对象。使用。使用。使用。使用ThreadThread类创建线程对象时,常用的构造方法是:类创建线程对象时,常用的构造方法是:类创建线程对象时,常用的构造方法是:类创建线程对象时,常用的构造方法是:Thread(RunnableThread(Runnable target);target);在创建线程对象时,向构造方法的参数传递一在创建线程对象时,向构造方法的参数传递一在创建线程对象时,向构造方法的参数传递一在创建线程对象时,向构造方法的参数传递一个实现个实现个实现个实现RunnableRu
8、nnable接口类的实例,该实例对象接口类的实例,该实例对象接口类的实例,该实例对象接口类的实例,该实例对象称为所创线程的称为所创线程的称为所创线程的称为所创线程的目标对象目标对象目标对象目标对象。P171【例例7-3】通过接口构造线程体通过接口构造线程体public class ep7_2_2 implements Runnablepublic class ep7_2_2 implements RunnableThread teacher=new Thread(this);Thread teacher=new Thread(this);Thread student=new Thread(th
9、is);Thread student=new Thread(this);ComputerSum sum=new ComputerSum();ComputerSum sum=new ComputerSum();public ep7_2_2()public ep7_2_2()teacher.start();teacher.start();student.start();student.start();public static void main(String args)public static void main(String args)new ep7_2_2();new ep7_2_2();
10、public void run()public void run()if(Thread.if(Thread.currentThreadcurrentThread()=teacher)()=teacher)Thread.Thread.currentThreadcurrentThread().setName(teacher);().setName(teacher);elseelseThread.Thread.currentThreadcurrentThread().setName(student);().setName(student);for(int i=1;i=5;i+)for(int i=1
11、;i=5;i+)int m=sum.getSum();int m=sum.getSum();sum.setSum(m+1);sum.setSum(m+1);System.System.outout.println(.println(我是我是我是我是+Thread.Thread.currentThreadcurrentThread().getName()+,().getName()+,现在的和现在的和现在的和现在的和:+:+sum.getSum();sum.getSum();try try Thread.Thread.sleepsleep(200);(200);catch(Interrupted
12、Exception e)catch(InterruptedException e)构造线程体的两种方法的比较:构造线程体的两种方法的比较:1.使用使用Runnable接口接口 1)线程间容易实现共享数据和代码线程间容易实现共享数据和代码2)可以继承于其他类可以继承于其他类;2.直接继承直接继承Thread类类 1)不能再继承其他类(不利于代码升级)不能再继承其他类(不利于代码升级);2)编写简单,可以直接操纵线程编写简单,可以直接操纵线程两种方式下如何两种方式下如何实现多线程间的实现多线程间的数据共享?数据共享?7.4 操作线程的常用方法操作线程的常用方法 可以通过线程的方法进行基本的线程控制
13、,可以通过线程的方法进行基本的线程控制,常用方法如下:常用方法如下:1start()方法方法 线程调用该方法将启动线程,从新建状态线程调用该方法将启动线程,从新建状态进入就绪队列排队。一旦进入就绪队列排队。一旦CPU资源轮转到资源轮转到它时,就脱离主线程开始自己的生命周期。它时,就脱离主线程开始自己的生命周期。2run()方法方法 run()run()方法中定义线程对象被调度之后所执行的方法中定义线程对象被调度之后所执行的方法中定义线程对象被调度之后所执行的方法中定义线程对象被调度之后所执行的操作,是系统自动调用而用户不能引用的方法操作,是系统自动调用而用户不能引用的方法操作,是系统自动调用而
14、用户不能引用的方法操作,是系统自动调用而用户不能引用的方法当当当当run()run()方法执行完毕,线程就变成死亡状态方法执行完毕,线程就变成死亡状态方法执行完毕,线程就变成死亡状态方法执行完毕,线程就变成死亡状态在线程没有结束在线程没有结束在线程没有结束在线程没有结束run()run()方法之前,不要让线程再方法之前,不要让线程再方法之前,不要让线程再方法之前,不要让线程再调用调用调用调用start()start()方法,否则将发生方法,否则将发生方法,否则将发生方法,否则将发生IllegalThreadStateExceptionIllegalThreadStateException异常,
15、这一点在异常,这一点在异常,这一点在异常,这一点在写程序的时候需要注意。写程序的时候需要注意。写程序的时候需要注意。写程序的时候需要注意。3sleep(int millsecond)方法方法 sleep方法可以暂停一个线程的执行,在方法可以暂停一个线程的执行,在适当的时候再恢复其执行。就是让当前线适当的时候再恢复其执行。就是让当前线程睡眠(停止执行)若干程睡眠(停止执行)若干毫秒毫秒,线程由运,线程由运行中状态进入不可运行状态,停止执行时行中状态进入不可运行状态,停止执行时间到后线程进入间到后线程进入可运行状态可运行状态。Sleep()阻塞状态阻塞状态可运行状态可运行状态4isAlive()方
16、法方法 获取线程是否处于活动状态;获取线程是否处于活动状态;线程由线程由start()方法启动后,直到其被终止之间的任何时刻,方法启动后,直到其被终止之间的任何时刻,都处于都处于Alive状态。状态。线程处于新建状态时,调线程处于新建状态时,调用用isAlive()方法返回方法返回false,线程进入死亡状,线程进入死亡状态后,调用态后,调用isAlive()方法返回方法返回false。5currentThread()方法方法 currentThread()方法是方法是Thread类的类方类的类方法,可以直接通过类名调用,该方法返回法,可以直接通过类名调用,该方法返回当前正在使用当前正在使用CPU资源的线程。资源的线程。6 6Interrupt()Interrupt()方法方法方法方法 interrupt()interrupt()方法常用来方法常用来方法常用来方法常用来“吵醒吵醒吵醒吵醒”休眠的线程。但休眠的线程。但休眠的线程。但休眠的线程。但线程调用线程调用线程调用线程调用sleepsleep方法处于休眠状态时,一个占有方法处于休眠状态时,一个占有方法处于休眠状态时,一个占有方法处于
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1