AI赋能Java语言编程:从入门到高阶 课件 第十二章 线程_第1页
AI赋能Java语言编程:从入门到高阶 课件 第十二章 线程_第2页
AI赋能Java语言编程:从入门到高阶 课件 第十二章 线程_第3页
AI赋能Java语言编程:从入门到高阶 课件 第十二章 线程_第4页
AI赋能Java语言编程:从入门到高阶 课件 第十二章 线程_第5页
已阅读5页,还剩39页未读 继续免费阅读

下载本文档

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

文档简介

Java线程Javathread第十二章目标/OBJECTIVE0102030405了解线程的概念、特点以及线程的操作方法熟悉线程的生命周期和调度机制优先级了解线程状态转换了解线程同步原理,掌握线程同步的方法掌握实现线程交互的方法01线程和多线程12.1线程和多线程1.线程的概念线程是操作系统能够进行运算调度的最小单位,它被包含在进程中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。在UnixSystemV及SunOS中也被称为轻量进程(lightweightprocesses),但轻量进程更多指内核线程(kernelthread),而把用户线程(userthread)称为线程。为了实现多线程的效果,Java语言把线程或执行环境当作一个封装对象,包含CPU及自己的程序代码和数据,由虚拟机提供控制。Java类库中的类java.lang.Thread允许创建这样的线程,并可控制所创建的线程。12.1线程和多线程2.线程的特点及结构(1)线程的特点·线程是轻型实体,只有一点必不可少的资源,即程序、数据和TCB(ThreadControlBlock)。·线程是是独立调度和分派的基本单位,在多核或多CPU的系统上可以提高程序的执行效率。·线程可以共享进程资源,如地址空间、文件描述符和信号处理等。·线程之间可以通过共享内存或消息传递进行通信,但需要使用同步机制来保证数据的一致性。12.1线程和多线程(2)线程的结构·虚拟CPU,封装在java.lang.Thread类中,控制着整个线程的运行。·执行的代码,传递给Thread类,由Thread类控制顺序执行。·处理的数据,传递给Thread类,是代码执行过程中所要处理的数据。02线程的状态12.2线程的状态Java的线程是通过Java的软件包java.lang中定义的类Thread来实现的,生成一个Thread类的对象后,就生成了一个线程,可以通过操作该对象实现启动线程、终止线程、挂起线程等操作。1.线程的生命周期线程是一个动态执行的过程,它也有一个从产生到死亡的过程。12.2线程的状态2.线程的状态分类线程的状态是指线程在执行过程中的不同阶段。线程的状态可以分为以下几种:1.新建状态(New):线程对象被创建后,就进入了新建状态。2.就绪状态(Runnable):也被称为“可执行状态”。线程对象被创建后,调用该对象的start()方法,从而启动该线程。3.运行状态(Running):线程获取CPU权限进行执行。需要注意的是,线程只能从就绪状态进入到运行状态。4.阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。5.死亡状态(Dead):线程执行完毕或者因异常退出了run()方法,该线程结束生命周期。12.2线程的状态在程序中常常调用interrupt()来终止线程。interrupt()不仅可以中断正在运行的线程,也可以中断处于阻塞状态的线程。当interrupt()中断处于阻塞状态的线程时,系统会出现InterruptException异常。03创建线程12.3创建线程1.通过继承Thread类法创建线程Thread类中定义了许多可以完成线程处理工作的方法,因此可以通过定义一个Thread的子类来创建一个新的线程。继承得到的类必须重写run()方法,该方法是新线程的入口点。通过继承Thread类创建一个新线程包含一下几个步骤:1.定义一个Thread类的子类。2.用该子类创建一个对象。3.使用start()方法启动线程。12.3创建线程2.通过实现Runnable接口创建线程Runnable是Java中专门用来实现线程的接口,其中只定义了一个run()方法。因此,创建一个线程,最简单的方法是创建一个实现Runnable接口的类。通过实现Runnable接口创建线程具体步骤如下:1.创建一个类并实现Runnable接口。这个接口只有一个方法run(),需要在其中定义线程的逻辑。2.在类中实现run()方法,编写线程的逻辑代码。3.在主程序中创建一个Runnable对象的实例。12.3创建线程4.创建一个Thread对象,将Runnable对象作为参数传递给Thread的构造函数。5.调用Thread对象的start()方法,启动线程。12.3创建线程例12.1使用Runnable接口创建两个线程,并让两个线程同时打印自己的名字。Copilot指令:使用Runnable接口创建两个线程,并让两个线程同时打印自己的名字。12.3创建线程12.3创建线程3.通过Callable和Future创建线程Callable和Future是Java提供的一种异步编程的方式,可以在一个新的线程中执行一个有返回值的任务,并且可以获取任务的执行结果。通过Callable和Future创建线程的步骤如下:1.创建一个实现了Callable接口的类,并重写call方法,该方法是线程的执行体,并且有返回值3。2.创建一个FutureTask对象,用来包装Callable对象,该对象可以获取Callable对象的call方法的返回值45。3.创建一个线程池对象,用来管理线程的执行。4.将FutureTask对象作为参数,提交给线程池对象,创建一个新的线程。5.调用FutureTask对象的get方法,来获取子线程执行结束后的返回值。12.3创建线程Copilot指令:使用Callable和Future创建一个计算平方根的线程,计算并输出2的平方根。例12.2使用Callable和Future创建一个计算平方根的线程,计算并输出2的平方根。12.3创建线程12.3创建线程4.不同创建线程的方法的区别1.采用实现Runnable、Callable接口的方式创建多线程时,线程类只是实现了Runnable接口或Callable接口,还可以继承其他类。2.使用继承Thread类的方式创建多线程时,编写简单,如果需要访问当前线程,则无需使用Thread.currentThread()方法,直接使用this即可获得当前线程。04线程的优先级12.4线程的优先级1.线程的不同优先级

在笔记时,人们通常会用不同颜色标记一些重要内容,也就是所谓的“划重点”,不同的颜色代表了内容的重要程度,这有助于快速查找、记忆笔记中的重要内容。Java中的线程与之相似,每一个Java线程都有一个优先级,线程越重要优先级越高,这有助于CPU对线程的调度。

处于就绪状态的线程需要获得CPU的执行权才可以开始运行,当CPU需要执行一个多线程人物时,就需要根据不同进程的状态及优先级来进行调度。

Java线程的优先级为整数且有三个不同的取值。

1.MIN_PRIORITY:值为1

2.NORM_PRIORITY:值为53.MAX_PRIORITY:值为10

线程的默认优先级为NORM_PRIORITY(5)。12.4线程的优先级2.线程的调度方法Java中的线程调度由线程调度器完成,线程调度方法通常是抢占式的,拥有执行权的可执行线程会持续执行。当线程执行完毕或被阻塞时,等待执行的队列中的线程会获得执行权并开始执行。Java的线程调度方法如下:1.按优先级进行排序,优先级高的线程优先执行。2.线程被创建时会默认赋予与其父类相同的优先级,若无父类,则赋予其默认优先级NORM_PRIORITY(5)。3.优先级相同的线程按照”先进先出“的原则执行。Java中有多种有关线程优先级的方法。例如

Thread类的setPriority(int)方法可以直接设置线程的优先级。ThreadMXBean类的getThreadPriority(long)方法可以查询和设置线程的优先级。05线程的基本控制12.5线程的基本控制1.暂停与唤醒线程运行中的线程可以通过一些方法暂停,暂停线程也称为挂起。线程被暂停后必须通过一定的方法将其唤醒。被暂停后,线程就失去了执行权,若等待执行的队列中有其他线程则执行权会交给该线程,若无其他可运行的线程则会等待线程被唤醒后继续执行。以下是几种暂停线程的方法:1.sleep():该方法直接暂停该线程的执行,让线程“睡一会儿”,线程进入阻塞状态。2.yield():该方法使当前正在执行的线程暂停一次,允许其他线程执行,不阻塞,线程进入就绪状态,如果没有其他等待执行的线程,这个时候当前线程就会马上恢复执行。3.join():调用该方法的线程强制执行,进入运行状态。其他正在运行的线程进入阻塞状态,该线程执行完毕后,其他线程继续执行。唤醒线程的方法为notify()/notifyAll(),notify()方法用于唤醒在对象上等待的一个线程。并使它进入就绪状态;notifyAll()方法用于唤醒在对象上等待的所有线程。它会将等待队列中的所有线程都唤醒,并使它们进入就绪状态。12.5线程的基本控制2.结束线程结束线程有两种情况,一种为线程执行完毕自动结束,另一种为调用结束线程的方法来结束线程。例如从网络下载一个100M的文件,如果网速很慢,用户等得不耐烦,就可能在下载过程中点“取消”,这时,程序就需要中断下载线程的执行。通常调用interrupt()方法来结束线程。12.5线程的基本控制3.检查线程在不清楚一个线程的状态时,可以通过下列集中方法检查线程:1.isAlive()方法:isAlive()方法用于检查线程是否处于活动状态。如果线程已启动且尚未终止,则返回true;否则返回false。2.getState()方法:getState()方法用于获取线程的状态。它返回一个Thread.State枚举表示线程的状态,如NEW(新建)、RUNNABLE(可运行)、BLOCKED(阻塞)、WAITING(等待)、TIMED_WAITING(计时等待)和TERMINATED(终止)。3.isInterrupted()方法:isInterrupted()方法用于检查线程的中断状态。如果线程的中断状态为true,则返回true;否则返回false。注意,调用isInterrupted()方法不会清除线程的中断状态。4.interrupted()方法:interrupted()方法用于检查当前线程的中断状态,并清除中断状态。如果当前线程的中断状态为true,则返回true;否则返回false。06线程的同步问题12.6线程的同步问题1.线程间的资源互斥当多个线程同时运行时,线程的调度由操作系统决定,程序本身无法决定。因此,任何一个线程都有可能在任何指令处被操作系统暂停,然后在某个时间段后继续执行。所以当同时运行的多个线程需要用到同一个变量或同一段代码时,运行的结果就可能由于每个线程的执行状况不同而产生误差,即产生了资源互斥。为避免产生资源互斥现象,需要用到线程同步的方法。12.6线程的同步问题2.线程同步方法当线程间发生资源互斥的情况时,为了避免这种情况产生的影响,可以采取一些手段限制多个线程对同一个资源的使用。例如某部门迎新晚会前,各节目组均需要占用舞台进行彩排,规定舞台在同一时间内只能由一个节目组使用,这样即可让每个节目组都能顺利使用舞台并避免多个节目组同时占用舞台互相影响。相似地,在使用多线程编程时,可以通过给一个共享资源“上锁”,使其只能同时由一个线程使用来避免资源互斥现象,因此引入“对象互斥锁”概念。12.6线程的同步问题“对象互斥锁”阻止多个线程同时访问同一资源,每个对象的实例均可以有一个“对象互斥锁”。有多种方式实现“对象互斥锁”:1.使用关键字volatile声明变量。2.使用关键字synchronized声明方法或一段代码。一般情况下,经常使用关键字synchronized声明一个方法,该方法对多个线程需同时用到的变量进行了操作。07死锁12.7死锁当线程试图连续获取多个锁时,就可能发生死锁的情况,死锁产生的具体条件为:1.互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用2.不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。3.请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有。4.循环等待,即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。这样就形成了一个等待环路。当上述四个条件都成立的时候,便形成死锁。例如:一个程序中设计了两个线程,线程1和线程2,需要用到两个锁,锁1和锁2,两个线程同步执行时,线程1与线程2同步运行,线程1获得了锁1,线程2获得了锁2,之后线程1试图获取锁2,线程2试图获取锁1,两个线程进入无尽的等待,这就发生了死锁。08线程的交互12.8线程的交互在多线程编程中,多条线程并非都是毫无关联的,线程之间存在一些关联,需要一种通信手段实现交互才能顺利完成工作。一个典型的例子是生产者-消费者问题,生产者和消费者在同一时间段内共用同一个存储空间,生产者向空间里存放数据,而消费者取用数据,如果不加以协调可能会出现以下情况:存储空间已满,而生产者占用着它,消费者等着生产者让出空间从而取出产品,生产者等着消费者消费产品,从而向空间中添加产品。互相等待,从而发生死锁。为解决上述问题,就需要两者进行交互。12.8线程的交互实现线程的交互需要使用wait(),notify()/notifyAll()的同步机制,wait()使线程释放持有的“对象互斥锁”使线程可以获取这个锁,在储存空间没有可取出的新数据时,就需要使消费者退出储存空间,使生产者可以使用。该方法使thread线程释放持有的“对象锁”。相应地,生产者需要在放入产品后提醒消费者,使生产者退出储存空间后,消费者可以进入并取出数据。notify()/notifyAll使线程被唤醒,进入等待获取“对象锁”的队列中。12.8线程的交互例12.3使用wait()和notify()/notifyAll()同步机制,模拟生产者和消费者的问题。生产者线程负责生产物品,消费者线程负责消费物品。Copilot指令:使用wait()和notify()/notifyAll()同步机制,模拟生产者和消费者的问题。生产者线程负责生产物品,消费者线程负责消费物品。12.8线程的交互12.8线程的交互12.8

温馨提示

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

评论

0/150

提交评论