多线程

多线程(multithreading),是指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体处理性能。具有这种能力的系统包括对称多处理机、多核心处理器以及芯片级多处理或同时多线程处理器。在一个程序中,这些独立运行的程序片段叫作“线程”(Thread),利用它编程的概念就叫作“多线程处理” [1]  。
中文名
多线程
外文名
multithreading
用    途
实现多个线程并发执行的技术
对    象
计算机
含    义
从软件或者硬件上实现多个线程并发执行的技术
作    用
提升整体处理性能

简介

编辑

在计算机编程中,一个基本的概念就是同时对多个任务加以控制。许多程序设计问题都要求程序能够停下手头的工作,改为处理其他一些问题,再返回主进程。可以通过多种途径达到这个目的。最开始的时候,那些掌握机器低级语言的程序员编写一些“中断服务例程”,主进程的暂停是通过硬件级的中断实现的。尽管这是一种有用的方法,但编出的程序很难移植,由此造成了另一类的代价高昂问题。中断对那些实时性很强的任务来说是很有必要的。但对于其他许多问题,只要求将问题划分进入独立运行的程序片断中,使整个程序能更迅速地响应用户的请求 [2]  
最开始,线程只是用于分配单个处理器的处理时间的一种工具。但假如操作系统本身支持多个处理器,那么每个线程都可分配给一个不同的处理器,真正进入“并行运算”状态。从程序设计语言的角度看,多线程操作最有价值的特性之一就是程序员不必关心到底使用了多少个处理器。程序在逻辑意义上被分割为数个线程;假如机器本身安装了多个处理器,那么程序会运行得更快,毋需作出任何特殊的调校。根据前面的论述,大家可能感觉线程处理非常简单。但必须注意一个问题:共享资源!如果有多个线程同时运行,而且它们试图访问相同的资源,就会遇到一个问题。举个例子来说,两个线程不能将信息同时发送给一台打印机。为解决这个问题,对那些可共享的资源来说(比如打印机),它们在使用期间必须进入锁定状态。所以一个线程可将资源锁定,在完成了它的任务后,再解开(释放)这个锁,使其他线程可以接着使用同样的资源 [2]  
多线程(2张)

多线程是为了同步完成多项任务,不是为了提高运行效率,而是为了提高资源使用效率来提高系统的效率。线程是在同一时间需要完成多项任务的时候实现的 [2]  

原理

编辑

实现多线程是采用一种并发执行机制 [3]  
并发执行机制原理:简单地说就是把一个处理器划分为若干个短的时间片,每个时间片依次轮流地执行处理各个应用程序,由于一个时间片很短,相对于一个应用程序来说,就好像是处理器在为自己单独服务一样,从而达到多个应用程序在同时进行的效果 [3]  
多线程就是把操作系统中的这种并发执行机制原理运用在一个程序中,把一个程序划分为若干个子任务,多个子任务并发执行,每一个任务就是一个线程。这就是多线程程序 [3]  

优点

编辑

1、使用线程可以把占据时间长的程序中的任务放到后台去处理 [4]  
2、用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度 [4]  
3、程序的运行速度可能加快 [4]  
4、在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用了。在这种情况下可以释放一些珍贵的资源如内存占用等 [4]  
5、多线程技术在IOS软件开发中也有举足轻重的作用 [4]  

缺点

编辑

1、如果有大量的线程,会影响性能,因为操作系统需要在它们之间切换 [4]  
2、更多的线程需要更多的内存空间 [4]  
3、线程可能会给程序带来更多“bug”,因此要小心使用 [4]  
4、线程的中止需要考虑其对程序运行的影响 [4]  
5、通常块模型数据是在多个线程间共享的,需要防止线程死锁情况的发生 [4]  

优势

编辑

多进程程序结构和多线程程序结构有很大的不同,多线程程序结构相对于多进程程序结构有以下的优势: [5] 
1、方便的通信和数据交换
线程间有方便的通信和数据交换机制。对于不同进程来说,它们具有独立的数据空间,要进行数据的传递只能通过通信的方式进行,这种方式不仅费时,而且很不方便。线程则不然,由于同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其他线程所用,这不仅快捷,而且方便 [5]  
2、更高效地利用CPU
使用多线程可以加快应用程序的响应。这对图形界面的程序尤其有意义,当一个操作耗时很长时,整个系统都会等待这个操作,此时程序不会响应键盘、鼠标、菜单的操作,而使用多线程技术,将耗时长的操作置于一个新的线程,就可以避免这种尴尬的情况 [5]  
同时,多线程使多CPU系统更加有效。操作系统会保证当线程数不大于CPU数目时,不同的线程运行于不同的CPU上 [5]  

概念区分

编辑

线程与多线程
线程是系统对代码的执行进程,如果将系统当做一个员工,被安排执行某个任务的时候,他不会对任何其他的任务作出响应。只有当这个任务执行完毕,才可以重新给他分配任务。一个程序都有一个主线程,负责执行程序必要的任务 [6]  
当我们处理一个消耗大的任务(如上传或下载图片),如果让主线程执行这个任务,它会等到动作完成,才继续后面的代码。在这段时间之内,主线程处于“忙碌”状态,也就是无法执行任何其他功能。体现在界面上就是,用户的界面完全“卡死” [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 条评论

发表回复

Avatar placeholder

您的电子邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

蜀ICP备16001794号
© 2014 - 2024 linpxing.cn All right reserved.