ImageVerifierCode 换一换
格式:DOCX , 页数:19 ,大小:25.17KB ,
资源ID:1584195      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/1584195.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(Java二十三Java多线程.docx)为本站会员(b****2)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

Java二十三Java多线程.docx

1、Java二十三Java多线程本文由我司收集整编,推荐下载,如有疑问,请与我司联系Java(二十三)Java 多线程2018/03/17 1 一、线程概述 几乎所有的操作系统都支持同时运行多个任务,一个任务通常就是一个程序,每个运行中的程序就是一个进程。当一个程序运行时,内部可能包含了多个顺序执行流,每个顺序执行流就是一个线程。 1.线程和进程 几乎所有的操作系统都支持进程的概念,所有运行中的任务通常对应一个进程(Process)。当一个程序进入内存运行时,即变成一个进程。进程是处于运行过程中的程序,并具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位。 一般而言,进程包含如下三个特

2、征: 独立性:进程是系统中独立存在的实体,它可以拥有自己独立的资源,每一个进程都拥有自己私有的地址空间。在没有经过进程本身允许的情况下,一个用户进程不可以直接访问其他进程的地址空间。 动态性:进程与程序的区别在于,程序知识一个静态的指令集合,而进程是一个正在系统中活动的指令集合。在进程中加入了时间的概念。进程具有自己的生命周期和各种不同的状态,这些概念在程序中都是不具备的。 并发性:多个进程可以在单个处理器上并发执行,多个进程之间不会互相影响。 注意:并发性(concurrency)和并行性(parallel)是两个概念。并行指在同一时刻,有多条指令在多个处理器上同时执行; 并发指在同一时刻只

3、能有一条指令执行,但多个进程指令被快速轮换执行,使得在宏观上具有多个进程同时执行的效果。 现代的操作系统都支持多进程的并发,但在具体的实现细节上可能因为硬件和操作系统的不同而采用不同的策略。比较常用的方式有:共用式的多任务操作策略,例如 Windows3.1 和 Mac OS 9; 目前操作系统大多采用效率更高的抢占式多任务操作策略,例如 Windows NT、Windows 2000 以及 UNIX/Linux 等操作系统。 多线程则扩展了多进程的概念,使得同一个进程可以同时并发处理多个任务。线程(Thread)也被称作轻量级进程(Lightweight Process),线程是进程的执行单

4、元。就像进程在操作系统中的地位一样,线程在程序中是独立的、并发的执行流。当进程被初始化后,主线程就被创建了。对于绝大多数的应用程序来说,通常仅要本文由我司收集整编,推荐下载,如有疑问,请与我司联系求有一个主线程,但也可以在该进程内创建多条顺序执行流,这些顺序执行流就是线程,每个线程也是相互独立的。 2.多线程的优势 线程在程序中是独立的、并发的执行流,与分隔的进程相比,进程中线程之间的隔离程度要小。它们共享内存、文件句柄和其他每个进程应有的状态。 当操作系统创建一个进程时,必须为该进程分配独立的内存空间,并分配大量的相关资源;但创建一个线程则简单得多,因此使用多线程来实现并发比使用多进程实现并

5、发的性能要高得多。 总结起来,使用多线程编程具有如下几个有点: 进程之间不能共享内存,但线程之间共享内存非常容易。 系统创建进程时需要为该进程重新分配系统资源,但创建线程则代价小得多,因此使用多线程来实现多任务并发比多进程的效率高。 Java 语言内置了多线程功能支持,而不是单纯地作为底层操作系统的调度方式,从而简化了 Java 的多线程编程。 二、线程的创建和启动 Java 使用 Thread 类代表线程,所有的线程对象都必须是 Thread 类或其子类的实例。每个线程的作用是完成一定的任务,实际上就是执行一段程序流(一段顺序执行的代码)。Java 使用线程执行体来代表这段程序流。 1.继承

6、 Thread 类创建线程类 通过继承 Thread 类来创建并启动多线程的步骤如下: 1.定义 Thread 类的子类,并重写该类的 run()方法,该 run()方法的方法体就代表了线程需要完成的任务。因此把 run()方法称为线程执行体。 2.创建 Thread 子类的实例,即创建了线程对象。 3.调用线程对象的 start()方法来启动该线程。 2.实现 Runnable 接口创建线程类 实现 Runnable 接口来创建并启动多线程的步骤如下: - 定义 Runnable 接口的实现类,并重写该接口的 run()方法,该 run()方法的方法体同样是该线程的线程执行体。 - 创建 R

7、unnable 实现类的实例,并以此实例作为 Thread 的 target 来创建 Thread 对象,该 Thread 对象才是真正的线程对象。 - 调用线程对象的 start()方法来启动该线程 3.使用 Callable 和 Future 创建线程 前面已经指出,通过实现 Runnable 接口创建多线程时,Thread 类的作用就是把 run()方法包装成线程执行体。那么是否可以直本文由我司收集整编,推荐下载,如有疑问,请与我司联系接把任意方法都包装成线程执行体呢?Java 目前不行!但 Java 的模仿者 C#可以(C#可以把任意方法包装成线程执行体,包括有返回值的方法)。 也许受

8、此启发,从 Java 5 开始,Java 提供了 Callable 接口,该接口怎么看都像是 Runnable 接口的增强版,Callable 接口提供了一个 call()方法可以作为线程执行体,但 call()方法比 run()方法功能更强大。 call()方法可以有返回值 call()方法可以声明抛出异常 因此完全可以提供一个Callable 对象作为 Thread 的 target,而该线程的线程执行体就是该 Callable 对象的call()方法。问题是:Callable 接口是 Java 5 新增的接口,而且它不是 Runnable 接口的子接口,因此 Callable 对象不能直

9、接作为 Thread 的 target。而且 call()方法还有一个返回值call()方法并不是直接调用,它是作为线程执行体被调用的。那么如何获取 call()方法的返回值呢? Java 5 提供了 Future 接口来代表 Callable 接口里 call()方法的返回值,并为 Future 接口提供了一个 FutureTask 实现类,该实现类实现了Future 接口,并实现了 Runnable 接口可以作为 Thread 类的 target。 创建并启动有返回值的线程的步骤如下: 创建 Callable 接口的实现类,并实现 call()方法,该 call()方法将作为线程执行体,且

10、该 call()方法有返回值,再创建 Callable 实现类的实例。从 Java 8 开始,可以直接使用 Lambda 表达式创建 Callable 对象 使用 FutureTask 类来包装 Callable 对象,该 FutureTask 对象封装了该 Callable 对象的 call()方法的返回值 使用FutureTask 对象作为 Thread 对象的 target 创建并启动新线程。 调用 FutureTask 对象的 get()方法来获得子线程执行结束后的返回值。 4.创建线程的三种方式对比采用实现 Runnable、Callable 接口的方式创建多线程的优缺点: - 线程

11、类只是实现了 Runnable 接口或 Callable 接口,还可以继承其他类。 - 在这种方式下,多个线程可以共享同一个 target 对象,因此非常适合多个相同线程来处理同一份资源的情况,从而可以将 CPU、代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。 - 劣势是,编程稍稍复杂,如果需要访问当前线程,则必须使用Thread.currentThread()方法。本文由我司收集整编,推荐下载,如有疑问,请与我司联系 采用继承 Thread 类的方式创建多线程的优缺点: 劣势是,因为线程类已经继承了 Thread 类,因此不能再继承其他父类 优势是,编写简单,如果需要访问当前线

12、程,则无须使用 Thread.currentThread()方法,直接使用 this 即可获得当前线程 鉴于上面分析,因此一般推荐采用实现 Runnable接口、Callable 接口的方式来创建多线程。 三、线程的声明周期 当线程被创建并启动以后,它既不是已启动就进入了执行状态,也不是一直处于执行状态,在线程的生命周期中,它要经过新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)和死亡(Dead)5 种状态。尤其是当线程启动以后,它不可能一直“霸占”着 CPU 独自运行,因此 CPU 需要在多条线程之间切换,于是线程状态也会多次在运行、阻塞之间切换。 1

13、.新建和就绪状态 当程序使用 new 关键字创建了一个线程之后,该线程就处于新建状态,此时它和其他的 Java 对象一样,仅仅由 Java 虚拟机为其分配内存,并初始化其成员变量的值。此时的线程对象没有表现成任何线程的动态特征,程序也不会执行线程的线程执行体。 当线程对象调用了 start()方法之后,该线程就处于就绪状态,Java 虚拟机会为其创建方法调用栈和程序计数器,处于这个状态中的线程并没有开始执行,只是表示该线程可以运行了。至于该线程何时开始运行,取决于 JVM 里线程调度器的调度。 注意 启动线程使用 start()方法,而不是 run()方法!永远不要调用线程对象的run()方法

14、!调用 start()方法来启动线程,系统会把该 run()方法当成线程执行体来处理;但如果直接调用线程对象的 run()方法,则 run()方法立即就会被执行,而且在run()方法返回之前其他线程无法并发执行也就是说,如果直接调用线程对象的run()方法,系统把线程对象当成一个普通对象,而 run()方法也是一个普通方法,而不是线程执行体。 调用线程对象的 start()方法之后,该线程立即进入就绪状态,但并未进入运行状态。如果希望调用子线程的 start()方法后子线程立即开始执行,程序可以使用本文由我司收集整编,推荐下载,如有疑问,请与我司联系Thread.sleep(1)来让当前运行的

15、线程(主线程)睡眠 1 毫秒。这样就可以让子线程立即开始执行。 2.运行和阻塞状态 如果处于就绪状态的线程获得了 CPU,开始执行 run()方法的线程执行体,则该线程处于运行状态。 当发生如下情况时,线程将会进入阻塞状态 线程调用 sleep()方法主动放弃所占用的处理器资源。 线程调用了一个阻塞式IO 方法,在该方法返回之前,该线程被阻塞。 线程试图获得一个同步监视器,但该同步监视器正被其他线程所持有。 线程在等待某个通知(notify) 程序调用了线程的 suspend()方法将该线程挂起。但这个方法容易导致死锁,因此应该尽量避免使用该方法。 被阻塞的线程会在合适的时候重新进入就绪状态,注意是就绪状态,而不是运行状态。 针对上面几种情况,当发生如下特定的情况时可以解除上面的阻塞,让该线程重新进入就绪状态。 调用 sleep()方法的线程经过了指定时间 线程调用的阻塞式 IO 方法已经返回。线程成功地获得了试图取得的同步监视器 线程正在等待某个通知时,其他线程发出了一个通知。 处于挂起状态的线程被调用了 resume()恢复方法 下图显示了线程状态转换图 3.线程死亡 线程会以如下三种方式结束,结束后处于死亡状

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1