




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
11.1线程概述11.2线程的创建11.3线程的生命周期11.4线程的调度11.5多线程同步11.1线程概述在计算机里被启动的独立运行的程序叫作进程(process)。单击键盘的组合键“Ctrl+Alt+Delete”,进入“任务管理器”,单击“更多”选项,就可以看到如图11-1-1所示的任务管理器窗口。在“进程”选项卡中可以看到当前计算机系统运行的程序,如浏览器、PPT和Word等,以及系统现在运行的进程,例如ACE2-Server等。这里需要注意的是,计算机程序与进程是两个不同的概念。计算机程序是一组计算机能识别和执行的指令,运行于计算机操作系统上,满足人们某种需求的软件工具,而进程是一个程序的一次执行过程,是系统运行程序的基本单位。因此,进程是程序运行的基本单位。当计算机开启一个进程时,就会将对应的程序及相关的资源调配到内存中,每个进程在内存中都有相对独立的存储单元。线程(Thread)是进程中的一个执行单元,也是操作系统能够进行运算调度的最小单位。线程负责当前进程中程序的执行,就好比社区医院在为老年人提供体检活动时,有专员做登记、有专员做血糖检查、有专员做外科检查等,这些专员就类似于一个个的线程。线程在内存中共享一块储存空间,但相对独立运行。线程结束,进程不一定结束;进程结束,它所包含的所有线程都会结束。简而言之,一个程序运行时至少有一个进程,一个进程中至少有一个线程。在多任务操作系统中,如果计算机是单核CPU,所有线程(任务)依次执行,CPU完成一个任务再进行下一个任务,这种执行方式叫作单线程。如果CPU在很小的时间间隔交替执行多个线程(任务),任一个时刻点上只有一个线程在CPU上运行,用户只是感觉计算机在同时执行多项任务,就叫作多线程,也叫并发。如果计算机是多核CPU,那么一个时刻点上可以有多个线程在不同CPU上同时运行。比如一个公司有多个员工,他们各司其职,这种执行方式叫作并行。实际上,并行包含了并发,多个CPU在并行运行时,每个CPU可以同时运行多个线程(并发)。对比单线程和多线程,它们各有优劣。单从CPU的运行效率上考虑,单任务进程及单线程效率是最高的,因为CPU没有任何进程及线程的切换开销。但对于一些耗时的任务,比如下载视频、播放音乐和等待用户输入文本等操作,CPU就会有很多空闲时间。因此,单线程存在CPU利用率不高的劣势,用户体验差。而多线程能够充分利用CPU,比如在等待用户输入文本的同时,可以利用空闲时间来下载视频、播放音乐等。因此,多线程的CPU利用率高,用户体验好。然而由于多线程需要不断地切换执行的任务,因此它的CPU运行效率并不高。在实际应用中多线程的应用最为广泛,绝大多数的多任务操作系统采用的都是多线程模式。需要注意的是,这里指的多线程不限于某个进程中的若干线程,而是在计算机中所有进程的线程。计算机的底层硬件和操作系统决定了这台计算机是否可以支持多线程操作。当一个程序中只有单个线程时,它在CPU并发操作中与其他运行程序的线程一起运行,对计算机而言仍然是多线程操作。此时的程序可称为单线程程序。在本书之前各章中编写的程序都是单线程程序,即按照main方法中编写的代码顺序执行,当main方法执行完毕,整个程序也就运行结束了。当一个程序中定义了多个线程时,该程序就是多线程程序,此时即使main方法执行完毕,程序可能还在运行。多线程程序在并发中可以同时执行当前进程中的多个任务,如图11-1-2所示。电脑版微信可以同时进行文字聊天(一对多)、视频聊天和传输文件(一对多)等任务。它们之间能够相对独立运行,开启或关闭某一个线程对其他的线程都不产生影响,对用户而言非常方便。在Java语言中提供了java.lang.Thread类、java.lang.Runnable接口和java.lang.callable接口,以及类内继承和定义的方法,以支持设计Java多线程程序。11.2线程的创建11.2.1线程的创建和运行方法Java语言中的线程使用Thread类来描述。Thread类直接继承自Object类。在Java单线程程序中,Java程序在运行main方法时就创建了名为main的线程,即主线程。主线程被放在名为main的线程组中,默认优先级为5。可以通过Thread类中的一些方法查询和设置线程的属性,如表11-2-1所示。对于单线程程序,当main程序执行完之后,主线程也就执行完毕,程序也随之执行完毕。在多线程程序中,只能有一个主线程。除了主线程外编程人员还可以自定义线程,称之为子线程。当所有的线程都执行完,或者在代码中直接调用了System.exit(0),即退出JVM,则程序执行结束。Thread类还实现了Runnable接口。Runnable接口中仅存在一个抽象方法run,Thread类中实现了run方法,但只是通过多态的形式调用了父类的run方法,并没有其他逻辑功能,其源代码如下:其中,target变量即是Runnable接口的对象引用,其源代码如下:创建一个线程,就是创建一个线程类的对象。运行一个线程,就是使用线程类的对象调用Thread类的start方法。此时,JVM会将该线程加入程序的线程组中,并运行该线程的run方法。当run方法执行完毕时,该线程也就执行完毕。因此,在创建线程时,就需要重写run方法,将线程要执行的功能代码写在run方法中。在JDK17中,Thread类提供了九种重载的构造方法,表10-2-2给出了四种常用的构造方法。由此可知,创建并运行一个线程可以通过两种方式:一种是自定义一个类继承Thread类,重写run方法,然后使用该类的对象调用start方法即可;另一种是自定义一个类实现Runnable接口,实现run方法,然后将该类的对象作为形参传入Thread类的构造方法中,使用实例化的线程对象调用start方法即可。在JDK1.5之后,官方又提供了FutureTask类和Callable接口来创建线程。其中,Callable接口作为FutureTask构造方法的形参,而FutureTask类又实现了Runnable接口,因此它本质上仍属于第二种构建线程的方式。由于FutureTask类和Callable接口支持泛型,并且Callable的运行方法call具有返回值,因此通常将它们创建线程的方式单独列出来作为第三种形式。接下来分别介绍这三种创建线程的方法。11.2.2继承Thread类创建线程该方法创建和运行线程的步骤如下:(1)自定义一个类,继承Thread类;(2)重写run方法,将线程逻辑放在run方法中;(3)创建该类的对象,在其他线程中调用start方法开启该线程。若创建了多个该类的对象并各自调用了start方法,则开启多个子线程。11.2.3实现Runnable接口创建线程通过这种形式创建并运行线程时,它的基本步骤如下:(1)自定义一个类实现Runnable接口,实现它的抽象方法run方法。(2)在其他线程中创建该类的对象,并作为形参传入Thread构造方法中。(3)使用Thread类的对象调用start方法,开启线程。11.2.4使用Callable和FutureTask创建线程使用Callable和FutureTask创建并运行线程的步骤如下:(1)自定义一个类实现Callable接口,实现它的call方法。(2)创建FutureTask类的对象,将Callable接口的实例类对象传进去。(3)创建线程对象,将FutureTask类的对象作为Runnable接口的对象引用传进去。(4)使用线程对象调用start方法,运行线程。(5)线程运行完毕后,返回值由FutureTask类的对象接收。11.3线程的生命周期在计算机中,同时会有多个线程来争夺CPU的使用权,线程在此过程中的状态会频繁地切换。为了能够清楚地描述线程的状态,方便线程管理,定义了线程的生命周期。线程的生命周期分为五个状态,即新建状态(New)、就绪状态(Runnable)、运行状态(Running)、阻塞状态(Blocked)和死亡状态(Terminated),如图11-3-1所示。线程生命周期的五个状态的内涵如下:(1)新建状态对应的是线程对象被创建好,但还没有调用start方法。此时对象只有自己的数据空间,还没有加入线程组,没有开始运行。(2)就绪状态对应的是线程对象已经调用了start方法,并且已经被加入到了线程组,具备争夺CPU使用权的资格,但目前没有在运行。(3)运行状态对应的是线程争夺到了CPU,正在执行它run或者call方法里面的代码。(4)阻塞状态对应的是线程被暂时取消了争夺CPU使用权的资格,暂时不可以运行。(5)死亡状态指的是线程执行完毕,或者执行期间抛出一个没有捕获的异常或错误。线程就此终止,它的生命周期也就结束了。这五个状态并非独立存在,而是存在着联系。图中的箭头指向表明了线程可以从某个状态转换到另一种状态。线程状态之间的转换包括以下几种情况:(1)新建状态可以转换成就绪状态;(2)就绪状态可以与运行状态相互转换;(3)运行状态可以转换成阻塞状态和死亡状态;(4)阻塞状态可以转换成就绪状态。这里需要注意的是,其他情况下状态是不可进行转换的。比如,就绪状态不能直接转换成阻塞状态。每一种状态转换都是需要条件的。比如,新建状态转换成就绪状态需要线程对象调用start方法;运行状态转换成死亡状态需要线程执行完毕,或者抛出一个没有捕获的异常或错误。其中,大多数线程会在就绪状态、运行状态和阻塞状态之间频繁地切换。下面针对这几种状态及其转换进行说明。1.就绪状态到运行状态的转换就绪状态到运行状态转换的条件是线程争夺到了CPU的使用权,CPU会分配一定的时间片去执行当前线程中的方法。2.运行状态到其他状态的转换线程在运行状态下,可能出现以下三种情况:(1)运行状态到就绪状态。线程代码在给定的时间内没有执行完毕,或者在代码中执行了线程让步方法yield,则线程就会自动转换成就绪状态,开始下一次CPU的争夺。有可能还会争夺到CPU继续执行,也有可能没有争夺到。(2)运行状态到死亡状态。线程代码在给定的时间内执行完毕了,该线程直接进入死亡状态,不复存在。(3)运行状态到阻塞状态。线程代码在执行过程中需要等待读写操作,或者执行了线程阻塞方法,包括join、sleep和wait方法,或者遇到了同步锁被占用的情况,则线程进入阻塞状态。3.阻塞状态到就绪状态的转换当线程处于阻塞状态时,需要出现一定的条件才可以转换为就绪状态。所谓“解铃还须系铃人”,根据线程进入阻塞状态原因的不同,线程从阻塞状态返回到就绪状态,可分为以下几种情况:(1)等待读写操作方法返回。如果线程是由于等待读写操作进入阻塞状态,那么只有当阻塞它的读写操作方法返回时才可以回到就绪状态。(2)等待线程阻塞方法join。如果线程是由于执行了线程阻塞方法join进入阻塞状态,那么只有等待调用join方法的线程执行完毕,或者超过等待时间才可以回到就绪状态;(3)等待线程休眠方法sleep。如果线程因执行了线程休眠方法sleep进入阻塞状态,那么必须等待该线程休眠时间过了才可以回到就绪状态。(4)执行等待方法wait。如果线程因执行了线程等待方法wait进入阻塞状态,那么必须等待其他的线程使用notify方法唤醒后才可以回到就绪状态。11.4线程的调度Java语言中的线程调度就是通过Thread类提供的操作方法对线程的状态进行管理,控制线程按照给定的逻辑顺序执行代码。除了setter和getter方法之外,表11-4-1所示的Thread类中的方法也比较常用。11.4.1线程优先级线程的优先级决定了线程在争夺CPU时的概率。线程的优先级越高,它获得CPU执行权的概率越大。需要注意的是,在一定时间内,优先级高的线程的执行次数不一定比优先级低的线程的执行次数多。在Java语言中,线程的优先级使用1~10之间的整数来表示,数字越大优先级越高。在创建一个线程时,如果没有指定它的优先级,默认的优先级为5,对应Thread类中的NORM_PRIORITY静态常量。此外,最低优先级(1)对应的静态常量为Thread.MIN_PRIORITY,最高优先级(10)对应的静态常量为Thread.MAX_PRIORITY。编程人员可以通过getPriority和setPriority方法来获取和设置线程的优先级。11.4.2线程休眠线程休眠就是让当前执行Thread.sleep方法的线程进入阻塞状态,直到过了休眠时间。这里的休眠方法有毫秒级和纳秒级两种。由于普通个人计算机的定时精度在毫秒级,这里仅演示毫秒级的线程休眠。11.4.3线程让步线程让步就是当前抢占到CPU的线程代码让出CPU的执行权,这个线程不再往下执行,回到就绪状态,继续下一轮的CPU争夺赛。这里需要注意的是,线程让步后,若再抢到CPU的执行权,将从让步方法之后继续执行。线程让步使用的是Thread类的yield静态方法。11.4.4线程插队线程插队是在线程a的run方式中执行线程b的join()方法,此时线程a进入阻塞状态,直到线程b全部执行完以后,或者超过指定的等待时间,线程a才会结束阻塞状态。需要注意的是,这里所描述的插队跟现实生活中排队买东西时的插队不一样。线程插队仅是b插队到了a前面,而不是插队到了所有线程之前。线程b仍然需要跟其他的线程争夺CPU的使用权,直到b执行完毕,或者超过等待时间,线程a才回到就绪状态,参与CPU的争夺。线程插队是通过join方法实现的。11.5多线程同步11.5.1同步代码块和同
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 特殊学校用具管理制度
- 环保农药使用管理制度
- 现场安全秩序管理制度
- 现金收款收据管理制度
- 班组岗位安全管理制度
- 理疗店铺运营管理制度
- 生产企业厂务管理制度
- 生产现场钥匙管理制度
- 生产职工考勤管理制度
- 公园里活动策划方案
- 第五单元《面积》(教学设计)-【大单元教学】三年级数学下册同步备课系列(人教版)
- 掼蛋考试试题及答案
- GA/T 2159-2024法庭科学资金数据清洗规程
- 企业风险管理-战略与绩效整合(中文版-雷泽佳译)
- 业务学习踝关节骨折
- 实景演出制作合同协议
- 迅镭激光切割机操作培训
- 《医疗机构重大事故隐患判定清单(试行)》知识培训
- 浙江省杭州市2024年中考英语真题(含答案)
- 《陆上风电场工程设计概算编制规定及费用标准》(NB-T 31011-2019)
- 装修管理规则-城市综合体---成都租户指引
评论
0/150
提交评论