版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Java第九章多线程程序设计基础篇从进程线程概念到并发编程核心技术Contents本章目录从进程与线程的基础概念出发,系统讲解线程的创建、同步、通信与协作机制。01进程与线程基础概念02线程创建与生命周期管理03线程同步与并发安全04线程通信与协作机制Chapter01进程与线程基础概念理解并发编程的基石:进程、线程及其关系OperatingSystem·Process什么是进程进程是操作系统进行资源分配和调度的基本单位,每个进程拥有独立的内存空间,是程序运行时的实体表现。Windows任务管理器·进程列表资源分配的最小单位进程是程序的一次执行过程,每个进程都有独立的内存地址空间独立运行的实体浏览器、视频播放器、Word编辑器各自独立运行、互不干扰多任务并行操作系统通过进程管理实现多任务并行,让用户感觉多个程序在"同时"运行进程间通信进程间通信需要特定机制(如管道、消息队列),因为内存空间相互隔离OPERATINGSYSTEM·THREAD什么是线程线程是CPU调度的最小单位,是进程内部的执行流。同一进程内的多个线程共享内存空间,能够高效协作完成复杂任务。01线程是进程内部的执行单元,一个进程至少包含一个主线程,也可以包含多个子线程并行执行主线程+子线程02同一进程内的线程共享该进程的内存空间和资源,这使得线程间的数据交换比进程间通信更加高效共享内存空间03Word程序的多线程实例:用户界面响应、拼写检查、后台打印等任务分别由不同线程执行UI·拼写·打印04线程切换的开销远小于进程切换,因此多线程是实现高并发应用的常用手段低开销·高并发Word多任务界面—UI响应、拼写检查、后台打印由不同线程并行驱动COMPARISON·OSFUNDAMENTALS进程与线程的核心区别进程与线程在资源隔离性、通信成本、切换开销三个维度存在本质差异,这些差异决定了多线程编程的设计思路与并发挑战。资源隔离性进程拥有独立内存空间,数据隔离安全但通信成本高线程共享进程内存,数据交换高效但需处理同步问题独立内存执行开销进程创建与销毁开销大,涉及内存分配与回收线程创建轻量,切换速度快,适合高并发场景高并发包含关系一个进程可包含多个线程,线程是进程的组成部分进程是资源分配单位,线程是CPU调度单位CPU调度CONCURRENCY为什么需要多线程多线程编程能够充分利用多核处理器优势,提升程序性能与响应速度,是现代高并发应用的基础技术支撑。充分利用多核CPU单线程只能利用一个核心,多线程可让多个核心同时工作,显著提升计算密集型任务效率多核并行提升用户体验将耗时操作放入后台线程,保持UI线程响应,避免界面假死,如下载时仍可操作界面UI响应处理并发请求Web服务器使用多线程模型同时响应成百上千个客户端请求,是互联网应用基础架构高并发异步任务处理定时任务、消息监听、事件响应等场景都需要独立线程,实现多任务并行能力多任务Chapter02线程创建与生命周期管理掌握Java线程的创建方式、启动方法与状态转换Java多线程基础创建线程方式一:继承Thread类继承Thread类并重写run()方法是最直观的线程创建方式,通过调用start()方法启动新线程执行任务逻辑。继承与重写自定义类继承Thread类,重写run()方法编写线程任务逻辑,这是最基础的线程创建方式extendsThread启动方式创建Thread子类实例后,必须调用start()方法启动线程,而非直接调用run()方法start()底层机制start()方法由JVM调用底层系统API创建新线程,新线程自动执行run()方法中的代码JVMNative常见误区直接调用run()只是普通方法调用,不会创建新线程,代码仍在当前线程顺序执行run()≠新线程JavaMultithreading创建线程方式二:实现Runnable接口实现Runnable接口是更灵活的线程创建方式,避免了单继承限制,是Java多线程编程的推荐实践。01自定义类实现Runnable接口,实现run()方法,然后将实例传递给Thread构造器创建线程对象newThread(runnable).start()02Runnable方式避免Java单继承限制,自定义类仍可继承其他父类,灵活性更高突破单继承03同一Runnable实例可被多个Thread对象共享,适合多个线程执行相同任务的场景多线共享04实际开发推荐使用Runnable接口方式,符合"组合优于继承"的设计原则Composition>InheritanceJavaMultithreading两种创建方式对比Thread继承方式简单直观但受限于单继承,Runnable接口方式更灵活且支持资源共享,是实际开发的推荐选择。Thread类vsRunnable接口对比维度继承Thread类实现Runnable接口继承限制占用继承名额,无法再继承其他类仍可继承其他父类,更灵活代码结构任务与线程解耦,职责清晰任务与线程分离,结构更优资源共享每个线程需要独立实例同一实例可被多线程共享推荐程度适合简单场景、学习使用实际开发推荐方式Runnable接口方式在灵活性和扩展性上优于Thread继承方式,是生产环境的首选Java线程管理线程启动与优先级线程通过start()方法启动执行,优先级设置可影响调度概率,但无法保证执行顺序,不应作为程序正确性的依赖。start()方法启动调用start()方法启动线程,JVM会创建新的执行流并在适当时机调用run()方法start()·run()优先级范围与设置线程优先级范围1-10,默认为5,通过setPriority()方法设置,数值越大优先级越高1–10·Default5操作系统调度决定优先级高的线程可能获得更多CPU时间片,但具体调度由操作系统决定,具有不确定性CPUTimeSlice不依赖优先级排序不能依赖线程优先级来保证执行顺序,程序正确性不应依赖于线程调度策略Non-deterministicTHREADLIFECYCLE线程的六种状态Java线程在生命周期中经历New、Runnable、Blocked、Waiting、TimedWaiting、Terminated六种状态,状态转换由程序逻辑与系统调度共同决定。01New线程对象已创建但尚未调用start()方法start()02Runnable线程正在运行或等待CPU调度分配时间片CPU03Blocked等待获取synchronized锁,进入锁竞争队列Lock04Waiting调用wait()等方法进入无限期等待,需被唤醒wait()05TimedWaiting调用sleep()或带超时的wait(),到时自动唤醒sleep()06Terminatedrun()方法执行完毕或异常退出,线程结束run()THREADLIFECYCLE线程状态转换图线程状态转换由方法调用与系统事件驱动,掌握转换触发条件是理解多线程程序行为的关键。01New→
Runnable调用start()方法,线程进入可运行状态等待调度02Runnable→
Blocked尝试获取已被其他线程持有的synchronized锁03Runnable→
Waiting调用Object.wait()、Thread.join()等方法进入等待04Runnable→
TimedWaiting调用Thread.sleep()或带超时参数的wait()方法05各等待状态→
Runnable获得锁、被唤醒、超时到期或join的线程结束06Runnable→
Terminatedrun()方法正常返回或抛出未捕获异常ThreadSynchronization线程等待:join()方法join()方法实现线程间的执行顺序控制,让调用线程等待目标线程执行完毕,是线程协作的基础机制。01阻塞等待机制调用thread.join()使当前线程阻塞,直到thread线程执行完毕后才继续执行阻塞02典型应用场景main线程启动工作线程后,需要等待工作线程完成任务再汇总结果汇总03超时参数控制join()可带超时参数,如join(1000)表示最多等待1秒,超时后当前线程继续执行1000ms04线程状态响应被join阻塞的线程处于Waiting或TimedWaiting状态,可响应中断抛出InterruptedExceptionWaitingChapter03线程同步与并发安全理解并发问题的根源,掌握synchronized锁机制与线程安全编程Concurrency并发安全问题的产生多线程同时访问共享资源时,由于指令交错的不可预测性,可能产生数据不一致的竞态条件问题。01竞态条件:多个线程同时读写共享变量,最终结果依赖于线程调度的时序,具有不确定性02经典案例:两个线程同时对余额1000元的账户各取100元,可能都读到1000后各自写回90003问题根源:读取-修改-写入操作不是原子的,中间可能被其他线程打断,导致数据覆盖04可见性问题:线程修改共享变量后,其他线程可能看不到最新值,因为各自使用工作内存副本JavaConcurrencysynchronized同步代码块synchronized关键字通过加锁机制保证代码块的原子性,确保同一时刻只有一个线程能执行临界区代码。01synchronized(lockObject){...}加锁语法:synchronized(lockObject){...}对指定对象加锁,保证代码块内指令原子执行02竞争机制:多个线程竞争同一把锁,获得锁的线程进入执行,未获得锁的线程进入Blocked状态等待03锁对象约束:锁对象必须是引用类型,多个线程必须使用同一个锁对象才能实现互斥04自动释放:synchronized代码块执行完毕或抛出异常时,锁会自动释放,无需手动解锁SYNCHRONIZATIONsynchronized修饰方法synchronized修饰方法时自动对整个方法加锁,实例方法锁this、静态方法锁Class对象,使用简洁但锁粒度较粗。实例方法锁对象synchronized修饰实例方法时,锁对象是this,即当前对象实例,同一实例的方法调用互斥this静态方法锁对象synchronized修饰静态方法时,锁对象是当前类的Class对象,所有实例的该方法调用互斥Class语法简洁优势方法级同步代码更简洁,无需显式指定锁对象,适合整个方法都是临界区的场景简洁粒度与性能权衡锁粒度较粗可能影响性能,若方法内只有部分代码需要同步,应使用同步代码块缩小锁范围粒度JavaConcurrencyvolatile关键字与可见性volatile保证变量的内存可见性,使线程修改立即对其他线程可见,但不能保证复合操作的原子性。内存直读直写每次读取从主内存获取最新值,每次修改立即写回主内存主内存解决可见性普通变量可能被缓存在线程工作内存,导致其他线程看不到最新修改可见性不保证原子性如i++操作仍可能被中断,复合操作仍需用synchronized保护非原子典型应用场景状态标志位、单例模式双重检查锁定、一次性发布的安全初始化4类场景Concurrency死锁问题与预防死锁是多线程相互等待对方释放锁导致的无限阻塞状态,通过统一加锁顺序、超时机制等策略可有效预防。死锁产生条件多线程各自持有不同锁,并互相试图获取对方已持有的锁,导致无限等待循环等待经典场景线程A持有锁1等待锁2,线程B持有锁2等待锁1,双方永远无法继续执行互相持有统一加锁顺序所有线程按相同顺序获取多把锁,打破循环等待条件顺序一致超时重试机制使用带超时的tryLock,获取锁失败时主动释放已持有的锁并重试tryLockCONCURRENCY·并发编程线程安全类设计线程安全类能在多线程环境下被正确使用而无需外部同步,通过封装与内部同步机制保证数据一致性。01线程安全定义类的行为在多线程环境下始终符合预期,无需调用方额外同步02设计原则封装共享可变状态,使用private修饰并通过synchronized方法访问03最小化可变性尽量使用final字段,减少需要同步的状态变量数量04线程安全集合Java并发包提供ConcurrentHashMap、CopyOnWriteArrayList、BlockingQueue等java.util.concurrentCHAPTER04线程通信与协作机制掌握wait/notify机制,理解线程间的协调运行原理Concurrencywait()与notify()方法wait()使线程等待并释放锁,notify()唤醒等待线程,两者配合实现线程间的协调通信,必须在synchronized块内调用。等待释放wait()使当前线程进入等待状态并释放持有的锁,直到被其他线程唤醒。调用后线程进入等待队列,不再参与CPU竞争。wait()调度唤醒notify()唤醒在该对象上等待的一个线程,具体唤醒哪个由JVM调度决定。被唤醒线程从等待队列移至阻塞队列。notify()同步约束必须在synchronized代码块内调用,且调用对象必须是当前持有的锁对象。违反此约束将抛出IllegalMonitorStateException。synchronized重新获锁已唤醒的线程需要重新获得锁后才能继续执行,不是立即恢复运行。获锁成功后从wait()处继续向下执行代码。re-lockJavaConcurrency·ThreadSchedulingnotify()vsnotifyAll()notify()只唤醒一个等待线程具有随机性,notifyAll()唤醒所有等待线程更安全,是多数场景的推荐选择。唤醒单个线程notify()只唤醒一个等待线程,具体唤醒哪个取决于操作系统调度,存在不确定性OS调度唤醒全部线程notifyAll()唤醒该锁上所有等待线程,让它们重新竞争锁,保证没有线程被遗漏全量唤醒避免死锁风险多生产者多消费者场景中,notify()可能唤醒同类线程导致死锁,notifyAll()更可靠死锁防御正确性优先性能考量:notifyAll()唤醒所有线程增加竞争开销,但正确性优先于性能正确性>性能CONCURRENCYPATTERN经典案例:生产者-消费者模型生产者-消费者模型通过有界缓冲区协调生产与消费节奏,是理解线程通信与wait/notify机制的经典实践。生产者线程向缓冲区放入产品,缓冲区满时调用wait()进入等待状态,放入成功后通过notifyAll()唤醒等待的消费者线程wait()/notifyAll()消费者线程从缓冲区取出产品,缓冲区空时调用wait()进入等待状态,取出成功后通过notifyAll()唤醒等待的生产者线程wait()/notifyAll()有界缓冲区通常使用BlockingQueue实现,自动处理线程等待与唤醒逻辑,内置容量控制,有效简化并发编程复杂度BlockingQueue异步协作解耦生产与消费过程,实现线程间高效异步协作,广泛应用于消息队列、任务调度与流式处理系统消息队列·任务调度CoreMechanism线程中断机制Java中断是协作式机制,通过标志位通知线程应该停止,线程自行决定如何响应,而非强制终止。发送中断请求interrupt()方法设置线程的中断标志位,不是立即终止线程,而是发出中断请求信号。interrupt()检查中断状态isInterrupted()方法检查中断标志,线程可据此决定是否退出当前任务。isInterrupted()等待状态异常处于等待状态的线程被中断会抛出InterruptedException,同时清除中断标志。InterruptedException正确处理中断捕获异常后恢复中断标志Thread.currentThread().interrupt(),让上层感知。restoreflagSummary本章知识总结Java多线程编程围绕线程管理、同步安全、通信协作、中断控制四大维度展开,是并发编程的核心基础。线程基础两种创建方式:继承Thread类、实现Runnable接口六种状态转
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026职业运动员专用防护设备技术标准与市场准入政策报告
- 2026食品加工业市场深度研究及发展趋势与投资收益预测研究报告
- 2026中国塑料薄膜制造行业市场现状供需研究投资评估规划分析报告
- 2026工业自动化控制系统网络安全加固方案报告
- 2026中国冷链物流行业数字化转型与效率提升路径分析报告
- 统编版七年级语文上册第二单元专题学习活动《有朋自远方来》学习任务单
- 2026Fast芯片组企业商业模式创新与盈利模式研究
- 2026中国新能源汽车智能图像识别系统行业市场深度调研及发展趋势与投资前景研究报告
- 2026设计营销策划行业市场深度分析及营销策划创意和品牌传播策略研究报告
- 2026汽车制造行业产能分析及智能转型路径探索与供应链优化报告
- 2026年食品营养学考试试题及答案
- (正式版)DB31∕T 405-2021 《集中空调通风系统卫生管理规范》
- 2026 城乡住建工程管理事业单位招聘考试招聘考试参考题库 含答案
- 建筑施工安全与消防管理试题
- 2026年防汛安全专项培训试题及答案
- 医院护工护理合同范本
- (高清版)DZT 0073-2016 电阻率剖面法技术规程
- 2024年福建省2024届高三3月省质检(高中毕业班适应性练习卷)英语试卷(含答案)
- 电力预防性试验课件
- 工程质量验收制度模版
- 营区消防安全培训课件
评论
0/150
提交评论