-
多线程
- 中文名
- 多线程
- 外文名
- multithreading
- 用 途
- 实现多个线程并发执行的技术
- 对 象
- 计算机
- 含 义
- 从软件或者硬件上实现多个线程并发执行的技术
- 作 用
- 提升整体处理性能
简介
在计算机编程中,一个基本的概念就是同时对多个任务加以控制。许多程序设计问题都要求程序能够停下手头的工作,改为处理其他一些问题,再返回主进程。可以通过多种途径达到这个目的。最开始的时候,那些掌握机器低级语言的程序员编写一些“中断服务例程”,主进程的暂停是通过硬件级的中断实现的。尽管这是一种有用的方法,但编出的程序很难移植,由此造成了另一类的代价高昂问题。中断对那些实时性很强的任务来说是很有必要的。但对于其他许多问题,只要求将问题划分进入独立运行的程序片断中,使整个程序能更迅速地响应用户的请求 [2] 。
最开始,线程只是用于分配单个处理器的处理时间的一种工具。但假如操作系统本身支持多个处理器,那么每个线程都可分配给一个不同的处理器,真正进入“并行运算”状态。从程序设计语言的角度看,多线程操作最有价值的特性之一就是程序员不必关心到底使用了多少个处理器。程序在逻辑意义上被分割为数个线程;假如机器本身安装了多个处理器,那么程序会运行得更快,毋需作出任何特殊的调校。根据前面的论述,大家可能感觉线程处理非常简单。但必须注意一个问题:共享资源!如果有多个线程同时运行,而且它们试图访问相同的资源,就会遇到一个问题。举个例子来说,两个线程不能将信息同时发送给一台打印机。为解决这个问题,对那些可共享的资源来说(比如打印机),它们在使用期间必须进入锁定状态。所以一个线程可将资源锁定,在完成了它的任务后,再解开(释放)这个锁,使其他线程可以接着使用同样的资源 [2] 。
原理
并发执行机制原理:简单地说就是把一个处理器划分为若干个短的时间片,每个时间片依次轮流地执行处理各个应用程序,由于一个时间片很短,相对于一个应用程序来说,就好像是处理器在为自己单独服务一样,从而达到多个应用程序在同时进行的效果 [3] 。
优点
缺点
优势
1、方便的通信和数据交换
线程间有方便的通信和数据交换机制。对于不同进程来说,它们具有独立的数据空间,要进行数据的传递只能通过通信的方式进行,这种方式不仅费时,而且很不方便。线程则不然,由于同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其他线程所用,这不仅快捷,而且方便 [5] 。
2、更高效地利用CPU
使用多线程可以加快应用程序的响应。这对图形界面的程序尤其有意义,当一个操作耗时很长时,整个系统都会等待这个操作,此时程序不会响应键盘、鼠标、菜单的操作,而使用多线程技术,将耗时长的操作置于一个新的线程,就可以避免这种尴尬的情况 [5] 。
概念区分
线程与多线程
线程是系统对代码的执行进程,如果将系统当做一个员工,被安排执行某个任务的时候,他不会对任何其他的任务作出响应。只有当这个任务执行完毕,才可以重新给他分配任务。缚一个程序都有一个主线程,负责执行程序必要的任务 [6] 。
当我们处理一个消耗大的任务(如上传或下载图片),如果让主线程执行这个任务,它会等到动作完成,才继续后面的代码。在这段时间之内,主线程处于“忙碌”状态,也就是无法执行任何其他功能。体现在界面上就是,用户的界面完全“卡死” [6] 。
应用
无论是过去还是现在,世界上大多数计算机仍然采用的是冯·诺依曼结构,这种结构的特点就是顺序处理,一个处理器在同个时刻只能处理一件事情。 Windows 95/NT采用一种全新的任务调度策略,它把一个进程划分为多个线程,每个线程轮流占用CPU的运算时间,操作系统不断地把线程挂起、唤醒、再挂起、再唤程,如此反复,由于现在CPU的速度比较快,给人的感觉是多个线程在同时执行,就好像有多个CPU存在于计算机中一样 [7] 。
多线程的一个典型例子是:用资源管理器复制文件时,一方面在进行磁盘读写操作,同时一张纸不停地从一个文件夹飘到另一个文件夹,这个飘的动作实际上是一段视频剪辑,也就是说,资源管理器能够同时进行磁盘读写和播放视频剪辑 [7] 。
多线程代码实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
public class SimpleThread { //私有的静态成员内部类,实现了Runnable接口 private static class ThreadMessage implements Runnable{ public void run(){ String[] info = { "消息1" , "消息2" , "消息3" , "消息4" }; try { for ( int i= 0 ;i<info.length;i++){ Thread.sleep( 4000 ); displayThreadMessage(info[i]); } } catch (InterruptedException e) { displayThreadMessage( "不能正常工作" ); } } } //显示消息,消息是当前线程的名字 static void displayThreadMessage(String message){ String threadName = Thread.currentThread().getName(); //格式化输出线程消息 System.out.format( "%s: %s%n" , threadName, message); } public static void main(String[] args) throws InterruptedException { // 中断ThreadMessage线程之前延迟的毫秒数(默认是一分钟) long delay = 1000 * 60 ; //如果有命令行参数,那么在命令行参数中给出推迟的时间 if (args.length> 0 ){ try { delay =Long.parseLong(args[ 0 ])* 1000 ; } catch (NumberFormatException e) { System.err.println( "参数必须是整数" ); System.exit( 1 ); } } displayThreadMessage( "启动线程ThreadMessage..." ); long startTime = System.currentTimeMillis(); Thread t = new Thread( new ThreadMessage()); t.start(); displayThreadMessage( "等待线程ThreadMessage结速..." ); //循环直到ThreadMessage线程退出 while (t.isAlive()){ displayThreadMessage( "继续等待线程ThreadMessage..." ); //最多等待3秒钟ThreadMessage线程结速 t.join( 3000 ); //如果线程t运行的时间超过delay指定时间 if (((System.currentTimeMillis() - startTime) > delay) && t.isAlive()){ displayThreadMessage( "线程ThreadMessage运行时间太久了,不想等待!" ); t.interrupt(); t.join(); } } displayThreadMessage( "结速线程ThreadMessage!!!" ); } } |
词条图
L (木秀林 林平行 行由心)
有道无术,术可成;有术无道,止于术
——————————————————————————————————————
免责申明,信息来源于互联网,仅供学习参考,不可用于商业用途
有道无术,术可成;有术无道,止于术
——————————————————————————————————————
免责申明,信息来源于互联网,仅供学习参考,不可用于商业用途
0 条评论