




已阅读5页,还剩27页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第11讲Java多线程 一 进程与线程 进程一般是对操作系统而言的 例如 你打开word编辑文档 同时打开outlook收取邮件 我们可以说这时系统内有两个进程在运行 即多个程序几乎在同一时间执行多个任务 线程一般是对某一程序而言的 如上例 你打开outlook收新邮件的同时 还可以看已下载的邮件 这两件事没有相互干扰 那么我们说此时这一程序中至少有两个线程在运行 即每一个程序在同一时间内执行多个任务 从逻辑的观点来看 多线程意味着一个程序的多行语句同时执行 但是多线程并不等于多次启动一个程序 操作系统也不会把每个线程当作独立的进程来对待 一 进程与线程 两者的粒度不同 是两个不同层次上的概念 进程是由操作系统来管理的 而线程则是在一个程序 进程 内 可以看看win2000的任务管理器 不同进程的代码 内部数据和状态都是完全独立的 而一个程序内的多线程是共享同一块内存空间和同一组系统资源 有可能互相影响 线程本身的数据通常只有寄存器数据 以及一个程序执行时使用的堆栈 所以线程的切换比进程切换的负担要小 二 多线程 多线程的优势减轻编写交互频繁 涉及面多的程序的困难 如监听网络端口 程序的吞吐量会得到改善 同时监听多种设备 如网络端口 串口 并口以及其他外设 有多个处理器的系统 可以并发运行不同的线程 否则 任何时刻只有一个线程在运行 三 线程的调度 调度策略时间片抢占式 高优先级的线程抢占CPUJava的调度方法同优先级线程组成先进先出队列 使用时间片策略对高优先级 使用优先调度的抢占式策略 因此 java的线程调度是不分时的 同时启动多个线程后 不能保证各个线程轮流获得均等的CPU时间片 Java中 线程的优先级实际上无法保障线程的执行次序 只不过 优先级高的线程获取CPU资源的概率较大 优先级低的并非没机会执行 线程的调度不是跨平台的 它不仅仅取决于java虚拟机 还依赖于操作系统 四 java线程模型 虚拟的CPU 由java lang Thread类封装和虚拟CPU来实现 CPU所执行的代码 传递给Thread类对象 CPU所处理的数据 传递给Thread类对象 代码 数据 虚拟CPU Java线程模型 五 主线程 在任何Java程序启动时 一个线程立刻运行 即main方法对应的线程 该线程通常称为程序的主线程 主线程的特点 它是产生其他子线程的线程 它不一定是最后完成执行的线程 子线程可能在它结束之后还在运行 一个普通的程序 顺序执行 classCommonTest1 publicstaticvoidmain Stringargs Aa1 newA a1 1000 Aa2 newA a2 1000 a1 tt a2 tt a2 setCount 2000 classA privateintcount privateStringsflag publicA publicA Stringsflag intcount this sflag sflag this count count protectedintgetCount returncount protectedvoidsetCount intcount this count count protectedStringgetSflag returnsflag protectedvoidsetSflag Stringsflag this sflag sflag publicvoidtt for inti 0 i count i System out println Ain sflag nowis i 六 创建线程 通过java lang Thread来创建一个线程Thread的构造器 Thread Thread Runnabletarget Thread Runnabletarget Stringname Thread Stringname Thread ThreadGroupgroup Runnabletarget Thread ThreadGroupgroup Runnabletarget Stringname Thread ThreadGroupgroup Stringname 七 启动线程 每个线程都是通过某个特定Thread对象所对应的方法run 来完成其操作的 方法run 称为线程体 使用start 方法 线程进入Runnable 可运行 状态 它将向线程调度器注册这个线程 调用start 方法并不一定马上会执行这个线程 正如上面所说 它只是进入Runnable而不是Running 注意 不要直接在程序中调用线程的run 方法 创建并启动线程例子 例 TestThread publicclassTestThreadextendsThread publicvoidrun for inti 0 i 100 i System out println Count i publicstaticvoidmain String args TestThreadtt newTestThread 注意 不要直接调用run方法tt start 八 使用Runnable接口 通常有两种方式创建线程 1 使用Runnable接口可以将CPU 代码和数据分开 形成清晰的模型 还可以从其他类继承 保持程序风格的一致性 2 直接继承Thread类不能再从其他类继承 编写简单 可以直接操纵线程 无需使用Thread currentThread 由于继承了Thread后 类再不能继承别的类 即无法资源共享 所以一般我们采用实现Runnable接口的方法来创建线程 具体步骤 提供一个实现接口Runnable的类 实现run 方法 得到这个类的实例A New这个一个Thread对象 同时A作为参数传入 例如 Threadrunner newThread A 调用start启动线程例如 runner start 用Runnable创建线程 例 RunnableThread publicclassRunnableThreadimplementsRunnable 实现接口Runnable中的run方法publicvoidrun for intk 0 k 10 k System out println Count k 采用extendsThread方法创建线程ThreadTest1采用implementsRunnable方法创建线程ThreadTest2普通对象实现业务逻辑 继承对象实现RunnableThreadTest3 九 创建多线程 publicclassTestThread 主类publicstaticvoidmain Stringargs Runnerr newRunner 生成线程类对象rThreadt1 newThread r 创建线程对象t1Threadt2 newThread r 创建线程对象t2t1 start 启动线程t1t2 start 启动线程t2 classRunnerimplementsRunnable 线程类publicvoidrun for inti 0 i 20 i System out println No i 十 线程的优先级 线程的优先级用数字来表示 范围从1到10 即Thread MIN PRIORITY到Thread MAX PRIORITY 一个线程的缺省优先级是5 即Thread NORM PRIORITY 下述方法可以对优先级进行操作 intgetPriority 得到线程的优先级voidsetPriority intnewPriority 当线程被创建后 可通过此方法改变线程的优先级在一个线程中开启另外一个新线程 则新开线程称为该线程的子线程 子线程初始优先级与父线程相同 见下面的例题 注意 并不是所有的操作系统都支持所有级别 永远不要依赖优先级来决定你的线程运行顺序 publicclassTest publicstaticvoidmain String args Threadt1 newMyThread1 Threadt2 newThread newMyRunnable t1 setPriority 10 t2 setPriority 1 t2 start t1 start classMyRunnableimplementsRunnable publicvoidrun for inti 0 i 10 i System out println 线程2第 i 次执行 try Thread sleep 100 catch InterruptedExceptione e printStackTrace classMyThread1extendsThread publicvoidrun for inti 0 i 10 i System out println 线程1第 i 次执行 try Thread sleep 100 catch InterruptedExceptione e printStackTrace 十一 线程的状态 线程共有下面4种状态 1 new 新建 当你用new创建一个线程时 该线程尚未运行 2 runnable 可运行 一旦调用了start方法 该线程便是一个可运行的线程 可运行的线程可以尚未执行 也可以正在执行 取决于线程调度的结果 java文档并不将正在运行的情况视为一个专门的状态 3 blocked 被中断运行 当出现下列操作之一时 线程便进入中断状态 有人调用该线程的sleep 方法 该线程调用了wait 方法 该线程调用了一个在输入输出时中断的操作 也就是说 在输入和输出操作完成之前 该操作不会返回到它的调用程序 该线程试图锁定一个当前被另一个线程锁定了的对象4 dead 死亡 由于下面两个原因 线程将变成死线程 由于run方法的正常退出而自然死亡 没有捕获到的异常事件终止了run方法的执行 从而导致线程突然死亡 十一 线程的状态 一旦线程开始运行 它不必始终保持运行状态 实际上 正在运行的线程有时需要被中断 这样其它线程就有机会可以运行了 若要确定某个线程当前是否活着 也就是说确定它是否处于可运行状态或者被中断状态 可以使用isAlive方法 如果该线程是可运行线程或者被中断线程 那么该方法返回true 如果该线程仍然是个新建线程 或者该线程是个死线程 那么该方法返回false 注意 你无法确定一个活线程究竟是处于可运行状态还是被中断状态 也无法确定一个可运行线程是否正处在运行之中 另外 你也无法对尚未成为可运行的线程与已经死掉的线程进行区分 线程状态迁移图 十二 线程让步和睡眠 对于程序员来说 在编程时要注意给每个线程执行的时间和机会 主要是通过人为的让步 yield 方法 或者让线程睡眠的办法 调用sleep 方法 来让当前线程暂停行一段时间 然后由其它线程来争夺执行的机会 十三 线程的join方法 ThreadAPI包含了等待另一个线程完成的方法 join 方法 当调用join 时 调用线程将阻塞 直到目标线程完成为止 join 通常由使用线程的程序调用 以将大问题划分成许多小问题 每个小问题分配一个线程 当所有的小问题都得到处理后 再调用主线程来进一步操作 JoinThreadr newJoinThread Threadt newThread r t start try t join catch InterruptedExceptione 十四 多线程的互斥与同步 前面所提到的线程都是独立的 而且异步执行 也就是说每个线程都包含了运行时所需要的数据或方法 而不需要外部的资源或方法 也不必关心其它线程的状态或行为 但是经常有一些同时运行的线程需要共享数据 此时就需考虑其他线程的状态和行为 否则就不能保证程序的运行结果的正确性 有一个Counter类 有一个成员变量lngCounter 一个线程对lngCounter进行 运算 循环100次 另一个线程对lngCounter进行 运算 也循环100次 最后的结果是多少 注意 两个线程并非顺序交替执行 两个线程获得的counter值出现不一致 其中有一个是旧的 必须让一个线程的add 或del 都执行完 才能让另一个线程执行 有何方法 十五 互斥锁 为解决操作的不完整性问题 在Java语言中 引入了对象互斥锁的概念 来保证共享数据操作的完整性 每个对象都对应于一个可称为 互斥锁 的标记 这个标记用来保证在任一时刻 只能有一个线程访问该对象 关键字synchronized来与对象的互斥锁联系 当某个对象用synchronized修饰时 表明该对象在任一时刻只能由一个线程访问 synchronized counter inti counter getCount System out println sname j before i System out println nowin sname count i AddCounter i 1 System out println sname j after counter getCount 完整例子ThreadTest4 互斥锁synchronized synchronized除了象上面讲的放在对象前面限制一段代码的执行外 还可以放在方法声明中 表示整个方法为同步方法 则将this对象作为锁 publicsynchronizedvoidpush charc 如果一个线程一直占用一个对象的锁 则其他的线程将永远无法访问该对象 因此 需要在适当的时候 将对象锁归还 当线程执行到synchronized 块结束时 释放对象锁 当在synchronized 块中遇到break return或抛出exception 则自动释放对象锁 当一个线程调用wait 方法时 它放弃拥有的对象锁并进入blocked状态 在两个线程的add 或del 方法中首先检查lngCounter的值 如果lngCounter的值达到临界值 则通过wait 放弃释放Counter对象锁并使线程挂起 直到得到Counter对象的notify 通知或者时间到期才恢复运行 十六 线程协作 while counter getLngCounter 7 try counter wait catch InterruptedExceptione longv counter getLngCounter v counter setLngCounter v counter notify wait 方法 wait 方法是Object对象的方法 而不是Thread的方法 wait 方法
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025至2030中国AM和和FM收音机行业发展趋势分析与未来投资战略咨询研究报告
- 冷库主管工作总结
- 2025至2030中国心耳封堵器行业产业运行态势及投资规划深度研究报告
- 铁路隧道消防培训
- 2025年智能可穿戴设备个性化健康服务技术创新报告
- 欺诈性债务抵消:虚构合同解除与补偿协议
- 蒙氏混龄班老师工作总结
- 高铁站空调采购、安装及旅客舒适度提升合同
- 离婚协议书中财产分割、子女抚养及共同财产清算协议
- 离婚协议违约金及财产分配纠纷解决合同
- 危重病人抢救制度课件
- 家具制造业2025年原材料价格波动对行业市场发展趋势影响报告
- 山东省济南市2025届中考数学真题(含答案)
- 2025-2030农业传感器网络部署模式与精准农业实践案例
- 接手烂尾项目的合同范本
- 物业客服人员培训
- 2025-2026学年地质版(2024)小学体育与健康二年级(全一册)教学设计(附目录P173)
- 茶百道培训课件
- 2025至2030年中国制药装备行业市场全景分析及投资前景展望报告
- 2025北京京剧院招聘工作人员10人考试备考题库及答案解析
- 检修现场管理培训课件
评论
0/150
提交评论