




已阅读5页,还剩40页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第8章线程 郑莉 JAVA语言程序设计 2 本讲内容 线程基础线程的概念Thread类Runnable接口资源共享和线程同步线程间的通信线程的生命周期线程的优先级程序举例 3 线程的概念 进程 程序的一次执行线程 一个进程中的多个控制流通过多线程 一个进程表面上看同时可以执行一个以上的任务 并发多数程序设计语言不支持并发 支持多线程要借助于操作系统 原语 primitives Java是第一个支持内置线程操作的主流编程语言 线程基础 4 Thread类简介 线程类需要继承Thread类Thread的构造函数publicThread StringthreadName publicThread 在线程的run方法中编写线程的主要任务sleep方法使线程休眠interrupt方法中断一个运行中的线程isAlive方法检查线程的状态setName方法设置线程名join方法等待线程结束 以执行当前线程 线程基础 5 例8 1在新线程中计算整数的阶乘 publicclassEx8 1 publicstaticvoidmain String args System out println mainthreadstarts FactorialThreadthread newFactorialThread 10 thread start System out println newthreadstarted mainthreadends endmain 线程基础 classFactorialThreadcontrolsthreadexecutionclassFactorialThreadextendsThread privateintnum publicFactorialThread intnum this num num publicvoidrun inti num intresult 1 while i 0 result result i i i 1 System out println Thefactorialof num is result System out println newthreadends 运行结果如下 mainthreadstartsnewthreadstarted mainthreadendsThefactorialof10is3628800newthreadends 8 例8 2创建3个新线程 每个线程睡眠任意0 6秒钟 然后结束 publicclassEx8 2 publicstaticvoidmain String args 创建并命名每个线程TestThreadthread1 newTestThread thread1 TestThreadthread2 newTestThread thread2 TestThreadthread3 newTestThread thread3 System out println Startingthreads thread1 start 启动线程1thread2 start 启动线程2thread3 start 启动线程3System out println Threadsstarted mainends n 线程基础 classTestThreadextendsThread privateintsleepTime publicTestThread Stringname 构造函数 super name 调用基类构造函数为线程命名 获得随机休息毫秒数sleepTime int Math random 6000 publicvoidrun 线程启动并开始运行后要执行的方法 try System out println getName goingtosleepfor sleepTime Thread sleep sleepTime 线程休眠 catch InterruptedExceptionexception 运行结束 给出提示信息System out println getName finished 运行结果为 StartingthreadsThreadsstarted mainendsthread1goingtosleepfor3519thread2goingtosleepfor1689thread3goingtosleepfor5565thread2finishedthread1finishedthread3finished 11 Runnable接口 如果希望一个已经有基类的类支持多线程 则不能再继承Thread类了 Java不支持多继承 解决方法 使类实现Runnable接口 再与Thread类结合使用一个内部类提供Runnable的实现代码 将内部类的对象与Thread结合相对于Thread类 它更适合于多个线程处理同一资源 线程基础 12 例8 3使用Runnable接口实现例8 1功能 publicclassEx8 1 publicstaticvoidmain String args System out println mainthreadstarts FactorialThreadt newFactorialThread 10 newThread t start System out println newthreadstarted mainthreadends endmain 线程基础 classFactorialThreadcontrolsthreadexecutionclassFactorialThreadimplementsRunnable privateintnum publicFactorialThread intnum this num num publicvoidrun inti num intresult 1 while i 0 result result i i i 1 System out println Thefactorialof num is result System out println newthreadends 14 例8 4使用Runnable接口实现例8 2功能 publicclassEx8 4 publicstaticvoidmain String args 创建3个实现Runnable接口类的对象TestThreadthread1 newTestThread TestThreadthread2 newTestThread TestThreadthread3 newTestThread System out println Startingthreads 分别以三个对象为参数创建三个新线程 第二个参数为新线程命名并启动之newThread thread1 Thread1 start newThread thread2 Thread2 start newThread thread3 Thread3 start System out println Threadsstarted mainends n 线程基础 classTestThreadimplementsRunnable privateintsleepTime publicTestThread 构造方法 获得随机休息毫秒数sleepTime int Math random 6000 publicvoidrun 线程启动并开始运行后要执行的方法 try System out println Thread currentThread getName goingtosleepfor sleepTime Thread sleep sleepTime 线程休眠 catch InterruptedExceptionexception 运行结束 给出提示信息System out println Thread currentThread getName finished 运行结果如下 StartingthreadsThread1goingtosleepfor1487Thread2goingtosleepfor1133Threadsstarted mainendsThread3goingtosleepfor2328Thread2finishedThread1finishedThread3finished 17 资源共享和线程同步 独立的同时运行的线程有时需要共享一些数据并且考虑到彼此的状态和动作 例如生产 消费问题 生产线程产生数据流 然后这些数据流再被消费线程消费 具体来说 假设一个Java应用程序 其中有一个线程负责往文件写数据 另一个线程从同一个文件中往出都数据 因为涉及到同一个资源 这里是同一个文件 这两个线程必须保证某种方式的同步 当多个线程的执行代码来自同一个类的实例 若干个 时 即称它们共享相同的代码 当共享访问相同的对象时 即它们共享相同的数据 使用Runnable接口可以轻松实现多个线程共享相同数据 只要用同一个实现了Runnable接口的实例作为参数创建多个线程就可以了 线程基础 18 例8 5修改例8 4 只用一个Runnable类型的对象为参数创建3个新线程 publicclassEx8 5 publicstaticvoidmain String args 只创建1个实现Runnable接口类的对象TestThreadthread newTestThread System out println Startingthreads 只用一个Runnable类型对象为参数创建三个新线程 命名并启动之newThread thread Thread1 start newThread thread Thread2 start newThread thread Thread3 start System out println Threadsstarted mainends n 线程基础 classTestThreadimplementsRunnable privateintsleepTime publicTestThread 构造函数 获得随机休息毫秒数sleepTime int Math random 6000 publicvoidrun 线程启动并开始运行后要执行的方法 try System out println Thread currentThread getName goingtosleepfor sleepTime Thread sleep sleepTime 线程休眠 catch InterruptedExceptionexception 运行结束 给出提示信息System out println Thread currentThread getName finished StartingthreadsThread1goingtosleepfor966Thread2goingtosleepfor966Threadsstarted mainendsThread3goingtosleepfor966Thread1finishedThread2finishedThread3finished 21 例8 6用三个线程模拟三个售票口 总共出售200张票 publicclassEx8 6 publicstaticvoidmain String args 新建一个售票类的对象SellTicketst newSellTickets 用此对象作为参数创建3个新线程并启动newThread t start newThread t start newThread t start 线程基础 classSellTicketsimplementsRunnable 将共享的资源作为私有变量privateinttickets 200 publicvoidrun while tickets 0 直到没有票可售为止 System out println Thread currentThread getName issellingticket tickets 23 例8 7用两个线程模拟存票 卖票过程 publicclassEx8 7 publicstaticvoidmain String args 新建一个票类对象 总票数作为参数Ticketst newTickets 10 以票类对象为参数创建存票线程对象 并启动newProducer t start 以同一个票类对象为参数创建售票线程 并启动newConsumer t start 线程基础 classTickets 票类 intnumber 0 票号intsize 总票数 表示目前是否有票可售booleanavailable false 构造方法 传入总票数参数publicTickets intsize this size size classProducerextendsThread 存票线程 Ticketst null publicProducer Ticketst 构造函数以一个票类对象为参数 this t t publicvoidrun 限制循环条件为存票序号小于总票数while t number t size System out println Producerputsticket t number t available true 可以卖票 classConsumerextendsThread 售票线程 Ticketst null inti 0 publicConsumer Ticketst 构造函数以一个票类对象为参数 this t t publicvoidrun while i t size 循环条件为售票序号小于总票数 if t available true 运行结果Producerputsticket1Producerputsticket2Producerputsticket3Producerputsticket4Producerputsticket5Producerputsticket6Producerputsticket7Producerputsticket8Consumerbuysticket1Consumerbuysticket2Consumerbuysticket3Consumerbuysticket4Consumerbuysticket5Consumerbuysticket6Consumerbuysticket7Consumerbuysticket8Producerputsticket9Producerputsticket10死机 进入死循环 28 错误原因 假如售票线程运行到t available false之前 CPU切换到执行存票线程 存票线程将available置为true 但再次切换到售票线程后 售票线程执行t available false 则由于售票号目前还是8 小于总票数 且存票线程已经结束不再能将t available置为true 则售票线程陷入了死循环 线程基础 29 线程同步 Synchronization Java使用的同步机制是监视器 支持线程的互斥与同步互斥 许多线程在同一个共享数据上操作而互不干扰 同一时刻只能有一个线程访问该共享数据 因此有些方法或程序段在同一时刻只能被一个线程执行 称之为监视区 协作 多个线程可以有条件地同时操作共享数据执行监视区代码的线程在条件满足的情况下可以允许其它线程进入监视区 线程基础 30 线程间的通信 线程同步关键字 synchronized用于指定需要同步的代码段或方法 也就是监视区 wait 当前状态不适合本线程执行时 进入等待状态notify 随机唤醒一个等待的线程 本线程继续执行 notifyAll 唤醒所有等待的线程 本线程继续执行 线程基础 31 线程间的通信 线程被唤醒以后 还要等发出唤醒消息者释放监视器 这期间关键数据仍可能被改变 被唤醒线程的线程可能有多个 使用notifyAll时 被唤醒的线程开始执行时 一定要判断当前状态是否适合自己运行 线程基础 32 例8 8实现例8 7功能 将同步方法放在共享的资源类Tickets中 publicclassEx8 8 publicstaticvoidmain String args Ticketst newTickets 10 newProducer t start newConsumer t start 线程基础 classTickets intsize 票总数intnumber 0 存票序号inti 0 售票序号booleanavailable false 是否有待售的票publicTickets intsize this size size publicsynchronizedvoidput 同步代码块 实现存票的功能 System out println Producerputsticket number available true publicsynchronizedvoidsell 同步代码块 实现售票的功能 if available true classConsumerextendsThread Ticketst null 构造方法 使两线程共享票类对象publicConsumer Ticketst this t t publicvoidrun 如果售票数小于限定总量 则不断售票 while t i t size t sell 35 例8 9每存入一张票 就售一张票 售出后 再存入 publicclassEx8 8 publicstaticvoidmain String args Ticketst newTickets 10 newProducer t start newConsumer t start 线程基础 classTickets intsize intnumber 0 inti 0 booleanavailable false publicTickets intsize this size size publicsynchronizedvoidput if available 如果还有存票待售 则存票线程等待try wait catch Exceptione System out println Producerputsticket number available true notify 存票后唤醒售票线程开始售票 publicsynchronizedvoidsell if available 如果没有存票 则售票线程等待try wait catch Exceptione if i number System out println Consumerbuysticket i if i number try Thread sleep 1 catch Exceptione available false notify 售票后唤醒存票线程开始存票 classProducerextendsThread Ticketst null publicProducer Ticketst this t t publicvoidrun while t number t size t put classConsumerextendsThread Ticketst null publicConsumer Ticketst this t t publicvoidrun while t i t size t sell 运行结果如下 Produc
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 老年人睡眠照顾课件
- 《大学物理实验2》课程简介与教学大纲
- 老年人春节安全预防
- 老年人护理知识培训活动课件
- 酿酒知识培训目的课件
- 汇源PET新产品命名方向再讨论
- 实数高频基础考题分类训练(12种类型60道)解析版八年级数学上册提分专项训练
- 红米需要泡几个小时
- 天津市2025年中考历史试卷及答案
- 人物传记(第二单元)-2025-2026学年八年级语文上册阅读素养通关训练(原卷版)
- 北师大版数学一年级上全册每课练习试题
- 修剪指甲培智五年级上册生活适应教案
- 《昆虫记》整本书阅读教学设计
- DB61-T 1295-2019保水采煤技术规范
- 八年级上册英语开学第一课
- 民事纠纷委托律师合同书
- 《统计学(第二版)》全套教学课件
- 应知应会质量管理
- 跨文化传播-导论课件
- 博士后出站研究报告
- 危险货物道路运输规则jtt617-2018
评论
0/150
提交评论