初学者如何学习多线程

上传人:ji****72 文档编号:45904023 上传时间:2018-06-20 格式:PDF 页数:36 大小:975.34KB
返回 下载 相关 举报
初学者如何学习多线程_第1页
第1页 / 共36页
初学者如何学习多线程_第2页
第2页 / 共36页
初学者如何学习多线程_第3页
第3页 / 共36页
初学者如何学习多线程_第4页
第4页 / 共36页
初学者如何学习多线程_第5页
第5页 / 共36页
点击查看更多>>
资源描述

《初学者如何学习多线程》由会员分享,可在线阅读,更多相关《初学者如何学习多线程(36页珍藏版)》请在金锄头文库上搜索。

1、初学者如何学习多线程初学者如何学习多线程 Java 多线程初学者指南(多线程初学者指南(1):线程简介):线程简介 . 1 Java 多线程初学者指南(多线程初学者指南(2):用):用 Thread 类创建线程类创建线程 . 3 Java 多线程初学者指南(多线程初学者指南(3):使用):使用 Runnable 接口创建线程接口创建线程 . 6 Java 多线程初学者指南(多线程初学者指南(4):线程的生命周期):线程的生命周期 . 7 Java 多线程初学者指南(5) :join 方法的使用. 13 Java 多线程初学者指南(6) :慎重使用 volatile 关键字 . 14 Java

2、多线程初学者指南(7) :向线程传递数据的三种方法 . 16 Java 多线程初学者指南(8) :从线程返回数据的两种方法 . 19 Java 多线程初学者指南(9) :为什么要进行数据同步 . 21 Java 多线程初学者指南(10) :使用 Synchronized 关键字同步类方法 . 24 Java 多线程初学者指南(11) :使用 Synchronized 块同步方法 . 30 Java 多线程初学者指南(12) :使用 Synchronized 块同步变量 . 34 5Java 多线程初学者指南(12) :使用 块同步变量 . 34 Java 多线程初学者指南(多线程初学者指南(

3、1):线程简介):线程简介 一、线程概述一、线程概述 线程是程序运行的基本执行单元。当操作系统(不包括单线程的操作系统,如微软早期 的 DOS)在执行一个程序时,会在系统中建立一个进程,而在这个进程中,必须至少建立一 个线程(这个线程被称为主线程)来作为这个程序运行的入口点。因此,在操作系统中运行 的任何程序都至少有一个主线程。 进程和线程是现代操作系统中两个必不可少的运行模型。在操作系统中可以有多个进程, 这些进程包括系统进程 (由操作系统内部建立的进程) 和用户进程 (由用户程序建立的进程) ; 一个进程中可以有一个或多个线程。 进程和进程之间不共享内存, 也就是说系统中的进程是 在各自独

4、立的内存空间中运行的。 而一个进程中的线可以共享系统分派给这个进程的内存空 间。放放电影 线程不仅可以共享进程的内存,而且还拥有一个属于自己的内存空间,这段内存空间也 叫做线程栈,是在建立线程时由系统分配的,主要用来保存线程内部所使用的数据,如线程 执行函数中所定义的变量。 注意:任何一个线程在建立时都会执行一个函数,这个函数叫做线程执行函数。也可以 将这个函数看做线程的入口点 (类似于程序中的 main 函数) 。 无论使用什么语言或技术来建 立线程, 都必须执行这个函数 (这个函数的表现形式可能不一样, 但都会有一个这样的函数) 。 如在 Windows 中用于建立线程的 API 函数 C

5、reateThread 的第三个参数就是这个执行函数的 指针。 在操作系统将进程分成多个线程后,这些线程可以在操作系统的管理下并发执行,从而 大大提高了程序的运行效率。 虽然线程的执行从宏观上看是多个线程同时执行, 但实际上这 只是操作系统的障眼法。由于一块 CPU 同时只能执行一条指令,因此,在拥有一块 CPU 的 计算机上不可能同时执行两个任务。 而操作系统为了能提高程序的运行效率, 在一个线程空 闲时会撤下这个线程,并且会让其他的线程来执行,这种方式叫做线程调度。我们之所以从 表面上看是多个线程同时执行, 是因为不同线程之间切换的时间非常短, 而且在一般情况下 切换非常频繁。假设我们有线

6、程 A 和 B.在运行时,可能是 A 执行了 1 毫秒后,切换到 B 后, B 又执行了 1 毫秒,然后又切换到了 A,A 又执行 1 毫秒。由于 1 毫秒的时间对于普通人来 说是很难感知的,因此,从表面看上去就象 A 和 B 同时执行一样,但实际上 A 和 B 是交替 执行的。 二、线程给我们带来的好处二、线程给我们带来的好处 如果能合理地使用线程,将会减少开发和维护成本,甚至可以改善复杂应用程序的性能。 如在 GUI 应用程序中, 还以通过线程的异步特性来更好地处理事件; 在应用服务器程序中可 以通过建立多个线程来处理客户端的请求。线程甚至还可以简化虚拟机的实现,如 Java 虚 拟机(J

7、VM)的垃圾回收器(garbage collector)通常运行在一个或多个线程中。因此,使用 线程将会从以下五个方面来改善我们的应用程序: 1. 充分利用 CPU 资源 现在世界上大多数计算机只有一块 CPU.因此,充分利用 CPU 资源显得尤为重要。当执行 单线程程序时,由于在程序发生阻塞时 CPU 可能会处于空闲状态。这将造成大量的计算资 源的浪费。而在程序中使用多线程可以在某一个线程处于休眠或阻塞时,而 CPU 又恰好处 于空闲状态时来运行其他的线程。这样 CPU 就很难有空闲的时候。因此,CPU 资源就得到 了充分地利用。 2. 简化编程模型 如果程序只完成一项任务,那只要写一个单线

8、程的程序,并且按着执行这个任务的步骤 编写代码即可。但要完成多项任务,如果还使用单线程的话,那就得在在程序中判断每项任 务是否应该执行以及什么时候执行。如显示一个时钟的时、分、秒三个指针。使用单线程就 得在循环中逐一判断这三个指针的转动时间和角度。 如果使用三个线程分另来处理这三个指 针的显示, 那么对于每个线程来说就是指行一个单独的任务。 这样有助于开发人员对程序的 理解和维护。 3. 简化异步事件的处理 当一个服务器应用程序在接收不同的客户端连接时最简单地处理方法就是为每一个客户 端连接建立一个线程。 然后监听线程仍然负责监听来自客户端的请求。 如果这种应用程序采 用单线程来处理,当监听线

9、程接收到一个客户端请求后,开始读取客户端发来的数据,在读 完数据后,read 方法处于阻塞状态,也就是说,这个线程将无法再监听客户端请求了。而 要想在单线程中处理多个客户端请求, 就必须使用非阻塞的 Socket 连接和异步 I/O.但使用异 步 I/O 方式比使用同步 I/O 更难以控制,也更容易出错。因此,使用多线程和同步 I/O 可以 更容易地处理类似于多请求的异步事件。 4. 使 GUI 更有效率 使用单线程来处理 GUI 事件时,必须使用循环来对随时可能发生的 GUI 事件进行扫描, 在循环内部除了扫描 GUI 事件外,还得来执行其他的程序代码。如果这些代码太长,那么 GUI 事件就

10、会被“冻结” ,直到这些代码被执行完为止。 在现代的 GUI 框架 (如 SWING、 AWT 和 SWT) 中都使用了一个单独的事件分派线程 (event dispatch thread,EDT)来对 GUI 事件进行扫描。当我们按下一个按钮时,按钮的单击事件函 数会在这个事件分派线程中被调用。由于 EDT 的任务只是对 GUI 事件进行扫描,因此,这种方式对事件的反映是非常快的。 5. 节约成本 提高程序的执行效率一般有三种方法: (1)增加计算机的 CPU 个数。 (2)为一个程序启动多个进程 (3)在程序中使用多进程。 第一种方法是最容易做到的,但同时也是最昂贵的。这种方法不需要修改程

11、序,从理论 上说,任何程序都可以使用这种方法来提高执行效率。第二种方法虽然不用购买新的硬件, 但这种方式不容易共享数据, 如果这个程序要完成的任务需要必须要共享数据的话, 这种方 式就不太方便, 而且启动多个线程会消耗大量的系统资源。 第三种方法恰好弥补了第一种方 法的缺点,而又继承了它们的优点。也就是说,既不需要购买 CPU,也不会因为启太多的线 程而占用大量的系统资源 (在默认情况下, 一个线程所占的内存空间要远比一个进程所占的 内存空间小得多) ,并且多线程可以模拟多块 CPU 的运行方式,因此,使用多线程是提高程 序执行效率的最廉价的方式。 三、三、Java 的线程模型的线程模型 由于

12、 Java 是纯面向对象语言,因此,Java 的线程模型也是面向对象的。Java 通过 Thread 类将线程所必须的功能都封装了起来。要想建立一个线程,必须要有一个线程执行函数,这 个线程执行函数对应 Thread 类的 run 方法。Thread 类还有一个 start 方法,这个方法负责建 立线程,相当于调用 Windows 的建立线程函数 CreateThread.当调用 start 方法后,如果线程 建立成功,并自动调用 Thread 类的 run 方法。因此,任何继承 Thread 的 Java 类都可以通过 Thread 类的 start 方法来建立线程。如果想运行自己的线程执行

13、函数,那就要覆盖 Thread 类 的 run 方法。 在 Java 的线程模型中除了 Thread 类, 还有一个标识某个 Java 类是否可作为线程类的接口 Runnable,这个接口只有一个抽象方法 run,也就是 Java 线程模型的线程执行函数。因此, 一个线程类的唯一标准就是这个类是否实现了 Runnable 接口的 run 方法,也就是说,拥有 线程执行函数的类就是线程类。 从上面可以看出,在 Java 中建立线程有两种方法,一种是继承 Thread 类,另一种是实现 Runnable 接口,并通过 Thread 和实现 Runnable 的类来建立线程,其实这两种方法从本质上

14、说是一种方法,即都是通过 Thread 类来建立线程,并运行 run 方法的。但它们的大区别是 通过继承 Thread 类来建立线程,虽然在实现起来更容易,但由于 Java 不支持多继承,因此, 这个线程类如果继承了 Thread,就不能再继承其他的类了,因此,Java 线程模型提供了通过 实现 Runnable 接口的方法来建立线程, 这样线程类可以在必要的时候继承和业务有关的类, 而不是 Thread 类。 Java 多线程初学者指南(多线程初学者指南(2):用):用 Thread 类创建线类创建线程程 在 Java 中创建线程有两种方法:使用 Thread 类和使用 Runnable 接口。在使用 Runnable 接口时需要建立一个 Thread 实例。 因此, 无论是通过 Thread 类还是 Runnable 接口建立线程, 都必须建立 T

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号