



全文预览已结束
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
多线程编程一直是程序员比较头痛和心虚的地方,因为线程执行顺序的不可预知性和调试时候的困难,让不少人在面对多线程的情况下选择了逃避,采用单线程的方式,其实只要我们对线程有了明确的认识,再加上Java内置的对多线程的天然支持,多线程编程不再是一道难以逾越的鸿沟。 一进程、线程、并发执行 关于进程、线程、并发执行的概念,我们先来看下面的一段话: “一般来说,当运行一个应用程序的时候,就启动了一个进程,当然有些会启动多个进程。启动进程的时候,操作系统会为进程分配资源,其中最主要的资源是内存空间,因为程序是在内存中运行的。 在进程中,有些程序流程块是可以乱序执行的,并且这个代码块可以同时被多次执行。实际上,这样的代码块就是线程体。线程是进程中乱序执行的代码流程。当多个线程同时运行的时候,这样的执行模式成为并发执行。“ 上面这段话引自51CTO网站“熔岩”的博客一篇文章Java多线程编程总结,读者可参考本文获得更详细的知识。 下面我以一个日常生活中简单的例子来说明进程和线程之间的区别和联系: 这副图是一个双向多车道的道路图,假如我们把整条道路看成是一个“进程”的话,那么图中由白色虚线分隔开来的各个车道就是进程中的各个“线程”了。 这些线程(车道)共享了进程(道路)的公共资源(土地资源)。 这些线程(车道)必须依赖于进程(道路),也就是说,线程不能脱离于进程而存在(就像离开了道路,车道也就没有意义了)。 这些线程(车道)之间可以并发执行(各个车道你走你的,我走我的),也可以互相同步(某些车道在交通灯亮时禁止继续前行或转弯,必须等待其它车道的车辆通行完毕)。 这些线程(车道)之间依靠代码逻辑(交通灯)来控制运行,一旦代码逻辑控制有误(死锁,多个线程同时竞争唯一资源),那么线程将陷入混乱,无序之中。 这些线程(车道)之间谁先运行是未知的,只有在线程刚好被分配到CPU时间片(交通灯变化)的那一刻才能知道二JVM与多线程 Java编写的程序都运行在在Java虚拟机(JVM)中,在JVM的内部,程序的多任务是通过线程来实现的。 每用java命令启动一个java应用程序,就会启动一个JVM进程。在同一个JVM进程中,有且只有一个进程,就是它自己。在这个JVM环境中,所有程序代码的运行都是以线程来运行的。JVM找到程序程序的入口点main(),然后运行main()方法,这样就产生了一个线程,这个线程称之为主线程。当main方法结束后,主线程运行完成。JVM进程也随即退出。 操作系统将进程线程进行管理,轮流(没有固定的顺序)分配每个进程很短的一段时间(不一定是均分),然后在每个进程内部,程序代码自己处理该进程内部线程的时间分配,多个线程之间相互的切换去执行,这个切换时间也是非常短的。 三Java语言对多线程的支持 Java语言对多线程的支持通过类Thread和接口Runnable来实现。这里就不多说了。这里重点强调两个地方:/ 主线程其它代码段ThreadClasssubThread=newThreadClass();subThread.start();/ 主线程其它代码段subThread.sleep(1000); 有人认为以下的代码在调用start()方法后,肯定是先启动子线程,然后主线程继续执行。在调用sleep()方法后CPU什么都不做,就在那里等待休眠的时间结束。实际上这种理解是错误的。因为: start()方法的调用后并不是立即执行多线程代码,而是使得该线程变为可运行态(Runnable),什么时候运行是由操作系统决定的。 Thread.sleep()方法调用目的是不让当前线程独自霸占该进程所获取的CPU资源,以留出一定时间给其他线程执行的机会(也就是靠内部自己协调)。四线程的状态切换 前面我们提到,由于线程何时执行是未知的,只有在CPU为线程分配到时间片时,线程才能真正执行。在线程执行的过程中,由可能会因为各种各样的原因的原因而暂停(就像前面所举的例子一样:汽车只有在交通灯变绿的时候才能够通行,而且在行驶的过程中可能会出现塞车,等待其它车辆通行或转弯的状况)。 这样线程就有了“状态”的概念,下面这副图,是从Java多线程编程总结一文中摘录出来的。很好的反映了线程在不同情况下的状态变化 1、新建状态(New):新创建了一个线程对象。 2、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。 3、运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。 4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种: 等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。 同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM把该线程放入锁池其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。 5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。五Java中线程的调度API Java中关于线程调度的API最主要的有下面几个: 线程睡眠:Thread.sleep(long millis)方法 线程等待:Object类中的wait()方法 线程让步:Thread.yield() 方法 线程加入:join()方法 线程唤醒:Object类中的notify()方法 关于这几个方法的详细应用,可以参考SUN的API,及Java多线程编程总结一文第七部分“线程的调度”。这里我重点总结一下这几个方法的区别和使用: 备注:sleep方法与wait方法的区别:sleep方法是静态方法,wait方法是非静态方法。 sleep方法在时间到后会自己“醒来”,但wait不能,必须由其它线程通过notify(All)方法让它“醒来” sleep方法通常用在不需要等待资源情况下的阻塞,像等待线程、数据库连接的情况一般用wait 备注:sleep/wait与yeld方法的区别:调用sleep或wait方法后,线程即进入block状态,而调用yeld方法后,线程进入runnable状态 备注:wait与join
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024北京二中高二(下)段考五数学试题及答案
- 2025年国际经济学基础知识测试题及答案
- 班团一体化培训
- 07-01向量及其线性运算章节课件
- 2025年工程管理基础知识考试试卷及答案
- 2025年数据科学硕士入学考试试卷及答案
- 2025年房地产经营与管理专业考核试卷及答案
- 2025年传统工艺文化传承考试试卷及答案
- 2025年城市交通工程师考试的主要试题及答案
- 2025年NFT与数字资产管理知识测试卷及答案
- 砂石销售提成管理制度
- 2025年湖南省中考生物试卷及答案
- 2025至2030中国地效飞行器行业产业运行态势及投资规划深度研究报告
- 高效化学灭菌技术-洞察及研究
- 融媒体保密管理制度
- 2025至2030中国消防产业市场深度调研及发展前景及有效策略与实施路径评估报告
- 2025江苏扬州宝应县“乡村振兴青年人才”招聘67人笔试参考题库附答案详解
- 地质灾害危险性评估合同模板
- 公司廉政纪律管理制度
- 2025年高考全国二卷数学高考真题解析 含参考答案
- 保密知识竞赛试题及答案
评论
0/150
提交评论