《JAVA语言与编程第11章Java多线程.ppt》由会员分享,可在线阅读,更多相关《JAVA语言与编程第11章Java多线程.ppt(19页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第第11章章 Java多线程多线程11.1 线程的概念线程的概念 现代操作系统中为了实现程序的并发执行而引入现代操作系统中为了实现程序的并发执行而引入了进程的概念了进程的概念.进程是程序的一次执行过程进程是程序的一次执行过程,是动态是动态的概念的概念.线程是比进程更小的执行单位线程是比进程更小的执行单位,是进程内部是进程内部独立的独立的,有序的指令流有序的指令流.多线程编程的含义是指可将程序任务分成几个并多线程编程的含义是指可将程序任务分成几个并行的子任务行的子任务,特别是在网络编程时特别是在网络编程时,使用多线程思想使用多线程思想编写的程序会具有很好的运行效率编写的程序会具有很好的运行效率,
2、可以充分利用系可以充分利用系统资源统资源.11.2 线程的创建线程的创建在在Java中创建线程有两种方法中创建线程有两种方法:一种方法是通过创一种方法是通过创Thread类的子类来实现类的子类来实现,另一种方法是通过实现另一种方法是通过实现Runnable接口的类接口的类来实现来实现.11.2.1Thread类与类与Runnnable接口接口就像应用程序必须从就像应用程序必须从main()方法开始执行一样方法开始执行一样,一个线程一个线程必须从必须从run()方法开始执行方法开始执行,而而run()方法声明在方法声明在java.lang.Runnable接口中接口中.1.Runnable接口接
3、口Runnable接口中只声明了一个接口中只声明了一个run()方法方法:publicvoidrun(),在创建并启动一个线程后在创建并启动一个线程后,系统自动调用系统自动调用run()方法方法.而而Runnable中的中的run()方法只是一个没有实现的方法方法只是一个没有实现的方法.一个线程一个线程对象必须实现对象必须实现run()方法来完成线程的所有活动方法来完成线程的所有活动,已实现的已实现的run()方法称为该对象的线程体方法称为该对象的线程体.11.2 线程的创建线程的创建(续续)2.Thread类类Thread类在类在java.lang包中定义包中定义,其构造函数如下其构造函数如
4、下:lpublicThread()lpublic Thread(Runnabletarget)lpublicThread(Runnabletarget,Stringname)lThread(Stringname)lThread(ThreadGroupgroup,Runnabletarget)lThread(ThreadGroupgroup,Runnabletarget,Stringname)lThread(ThreadGroupgroup,Stringname)11.2 线程的创建线程的创建(续续)11.2.2继承继承Thread类实现多线程类实现多线程创建线程最简单的方法就是继承创建线程最简
5、单的方法就是继承Thread类类,这个这个类已经为线程的创建和运行做了必要的配置类已经为线程的创建和运行做了必要的配置,并且提并且提供了大量的方法来方便我们控制自己的各个线程供了大量的方法来方便我们控制自己的各个线程.run()方法是方法是Thread类最重要的方法类最重要的方法,它被它被Thread类类的的start()方法调用方法调用.例例:SimpleThread.javanpublicclassSimpleThreadextendsThreadnintcount=1,number;npublicSimpleThread(intnum)nnumber=num;n(创建线程创建线程+num
6、ber);nnpublicvoidrun()nwhile(true)n(线程线程+number+:计数计数+count);nif(+count=4)return;nnnpublicstaticvoidmain(Stringargs)nfor(inti=0;i3;i+)nnewSimpleThread(i+1).start();nn11.2 线程的创建线程的创建(续续)11.2.3通过通过Runnable接口实现多线程接口实现多线程用继承用继承Thread类的方法创建线程简单明了类的方法创建线程简单明了,但是但是有一个缺点有一个缺点,就是如果类已经继承了一个父类就是如果类已经继承了一个父类,则不
7、则不能再继承能再继承Thread类类.此时可以使用创建线程的另外此时可以使用创建线程的另外一种方法一种方法,即首先创建实现即首先创建实现Runnable接口的类接口的类,再建再建立该类的对象立该类的对象,以此对象作为参数建立以此对象作为参数建立Thread类的类的对象对象,最后调用最后调用Thread类对象的类对象的start方法启动线程方法启动线程.11.2 线程的创建线程的创建(续续)例例:Runnable1.java,通过实现通过实现Runnable接口实现多接口实现多线程线程.npublicclassRunnable1implementsRunnablenintk=0;npublicR
8、unnable1(intk)nthis.k=k;nnpublicvoidrun()ninti=k;nwhile(i50)nSystem.out.print(i+);ni+=2;nn11.2 线程的创建线程的创建(续续)npublicstaticvoidmain(Stringargs)nRunnable1r1=newRunnable1(1);/创建具有线程体的目创建具有线程体的目标对象标对象nRunnable1r2=newRunnable1(2);nThreadt1=newThread(r1);/以目标对象创建线程以目标对象创建线程nThreadt2=newThread(r2);nt1.star
9、t();nt2.start();nfor(inti=0;i40;i+)System.out.print(A);nn注注:程序中程序中,线程语句的顺序只决定了线程产生的顺序线程语句的顺序只决定了线程产生的顺序,线程产生后并不立线程产生后并不立即执行即执行,而是和系统中的所有其他线程一起等待系统来执行它而是和系统中的所有其他线程一起等待系统来执行它,这时所这时所有线程执行的机会是均等的有线程执行的机会是均等的,所以这些线程的执行顺序由系统调度和所以这些线程的执行顺序由系统调度和控制控制,不由程序决定不由程序决定.11.3 线程优先级与线程调度策略线程优先级与线程调度策略 为了区分线程对操作系统以及
10、对用户的重要性为了区分线程对操作系统以及对用户的重要性,Java定义了线程的优先级控制和调度策略定义了线程的优先级控制和调度策略.11.3.1线程优先级线程优先级Java将线程的优先级分为将线程的优先级分为10个等级个等级,分别用分别用110之间的数字表示之间的数字表示,数字越大表示线程的优先级越高数字越大表示线程的优先级越高.相相应的应的,在在Thread类中定义了表示线程最低类中定义了表示线程最低,最高和普最高和普通优先级的通优先级的MIN_PRIORITY,MAX_PRIORITY和和NORMAL_PRIORITY,分别代表优先级等级分别代表优先级等级1,10和和5.一个线程被创建时一个
11、线程被创建时,默认的优先级为默认的优先级为5.新建线程将继新建线程将继承创建它的父线程的优先级承创建它的父线程的优先级.11.3 线程优先级与线程调度策略线程优先级与线程调度策略(续续)在应用程序中设置线程的优先级用在应用程序中设置线程的优先级用setPriority()方法方法,用用getPriority()方法可以获得当前线程的优先方法可以获得当前线程的优先级级,这两个方法的定义为这两个方法的定义为:setPriority(intnewPriority)getPriority()在在Java中有一种特殊的线程中有一种特殊的线程:守护守护(daemon)线程线程,它具有最低的优先级它具有最低
12、的优先级,用于为系统中的其他对象和线用于为系统中的其他对象和线程提供服务程提供服务.例如例如,始终在运行的垃圾收集器就是一始终在运行的垃圾收集器就是一个个daemon线程线程.11.3 线程优先级与线程调度策略线程优先级与线程调度策略(续续)11.3.2线程调度策略线程调度策略在单在单CPU系统上以某种顺序运行多个线程系统上以某种顺序运行多个线程,称为称为线线程调度程调度.Java的线程调度策略是一种基于优先级的抢占式的线程调度策略是一种基于优先级的抢占式调度策略调度策略.抢占式调度分为抢占式调度分为:独占方式和分时方式独占方式和分时方式.独占方式下独占方式下,当前执行的线程将一直执行下去当前
13、执行的线程将一直执行下去,直直到执行完毕或由于某种原因主动放弃到执行完毕或由于某种原因主动放弃CPU,或或CPU被被一个更高优先级的线程抢占一个更高优先级的线程抢占.分时方式下分时方式下,当前运行线程获得一个时间片当前运行线程获得一个时间片,时间时间片用完片用完,即使没有执行完也要让出即使没有执行完也要让出CPU,进入可运行进入可运行状态状态,等待下一个时间片的调度等待下一个时间片的调度.例例:ThreadPriorityDemo.java11.3 线程优先级与线程调度策略线程优先级与线程调度策略(续续)11.3.3Thread类中提供的线程调度的方法类中提供的线程调度的方法lpublicst
14、aticvoidsleep(longmillis)使当前执行使当前执行的线程睡眠指定的时间的线程睡眠指定的时间例:例:TestInterrupt.javapublicstaticvoidsleep(longmillis,intnanos)lpublicstaticvoidyield()调用调用yield方法方法,可以使具有当前线程相同优先级可以使具有当前线程相同优先级的线程有运行的机会的线程有运行的机会.如果有其他线程具有相同的优如果有其他线程具有相同的优先级并且处于可运行状态先级并且处于可运行状态,yield方法将把调用方法将把调用yield方法的线程放入可运行线程池方法的线程放入可运行线程
15、池,允许其他线程执行允许其他线程执行;反之反之,如果不存在如果不存在,则则yield方法什么也不做方法什么也不做,当前线当前线程程将继续运行将继续运行.例:例:TestYield.java11.3 线程优先级与线程调度策略线程优先级与线程调度策略(续续)lpublicfinalvoidjoin()使当前线程暂停执行使当前线程暂停执行,等等待调用该方法的线程结束后再继续执行本线程待调用该方法的线程结束后再继续执行本线程.例:例:TestJoin.javalpublicvoidwait()是从是从Object继承来的继承来的,它使当它使当前线程主动释放互斥锁前线程主动释放互斥锁,并进入互斥锁的等待
16、队列并进入互斥锁的等待队列.它的作用是使当前线程暂停执行它的作用是使当前线程暂停执行,等待某一事件的等待某一事件的发生发生,当这一事件发生时当这一事件发生时,一般通过调用一般通过调用notify或或notifyAll方法来唤醒该线程方法来唤醒该线程.publicvoidwait(longmillis)等待被唤醒或者再等待被唤醒或者再最多等待最多等待millis毫秒后自动执行毫秒后自动执行.11.3 线程优先级与线程调度策略线程优先级与线程调度策略(续续)lpublicvoidinterrupt()为线程设置一个中断标记为线程设置一个中断标记lpublicfinalvoidnotify()唤醒等
17、待队列中的一个唤醒等待队列中的一个线程线程,但是不能指定唤醒哪个线程但是不能指定唤醒哪个线程,任何满足了被任何满足了被唤醒条件的线程都有可能被唤醒唤醒条件的线程都有可能被唤醒lpublicfinalvoidnotifyAll()唤醒等待队列中的所唤醒等待队列中的所有线程有线程11.3 线程优先级与线程调度策略线程优先级与线程调度策略(续续)11.3.4线程的状态线程的状态在一个线程的生命周期中在一个线程的生命周期中,它总处于某一种状态它总处于某一种状态(1)创建状态创建状态:处于此状态时处于此状态时,它仅仅是一个空的线程它仅仅是一个空的线程对象对象,系统不为其分配资源系统不为其分配资源(2)就
18、绪状态就绪状态:在就绪队列中等待系统为其分配资源在就绪队列中等待系统为其分配资源(3)可运行状态可运行状态:系统为线程分配了它所需要的资源系统为线程分配了它所需要的资源(4)运行中状态运行中状态:线程占用线程占用CPU运行运行(5)阻塞状态阻塞状态:线程可能因为调用了线程可能因为调用了sleep方法方法,或者或者等待资源等而不得不让出等待资源等而不得不让出CPU(6)死亡状态死亡状态:线程执行结束线程执行结束,自然撤消或被停止自然撤消或被停止.11.4 线程的同步与死锁线程的同步与死锁11.4.1线程的同步线程的同步前面的线程都是异步的前面的线程都是异步的,即每个线程中都包含了运即每个线程中都
19、包含了运行时所需的所有数据和方法行时所需的所有数据和方法,而不需要外部的资源和而不需要外部的资源和方法方法,此时它不必关心其他线程的状态和行为此时它不必关心其他线程的状态和行为.但很但很多情况下一些线程需要共享数据多情况下一些线程需要共享数据.例如例如,一个线程向一个线程向文件中写数据文件中写数据,另一个线程从文件中读数据另一个线程从文件中读数据,此时就此时就要实现同步要实现同步.例:例:TestSync.java通常将系统中使用某类资源的线程称为消费者通常将系统中使用某类资源的线程称为消费者,而而产生和释放同类资源的线程称为生产者产生和释放同类资源的线程称为生产者,这即是线程这即是线程同步的一般模型同步的一般模型:生产者生产者-消费者问题消费者问题.11.4 线程的同步与死锁线程的同步与死锁(续续)例例:生产者生产从生产者生产从09的整数的整数,消费者负责读取消费者负责读取”生生产产”的数据的数据,我们希望生产者每生产一个数据我们希望生产者每生产一个数据,消费者就消费者就会将这个数据消费掉会将这个数据消费掉.WithoutSynchronization.javaSynchronization.java11.4 线程的同步与死锁线程的同步与死锁11.4.2线程的死锁线程的死锁例:例:TestDeadLock.java