Java 多线程 之 基本概念:程序、进程、线程

一、基本概念

  1、程序

    程序(program)是为完成特定任务、用某种语言编写的一组指令的集合。即指一段静态的代码,是静态对象。

  2、进程

    进程(process)是程序的一次执行过程,或是正在运行的一个程序。 是一个动态的过程:有它自身的产生、存在和消亡的过程

    如:运行中的微信、QQ、运行中的 MP3 播放器

    程序是静态的,进程是动态的;

    进程作为资源分配的单位,系统在运行时会为每个进程分配不同的内存区域。

    

  3、线程

    线程(Thread)进程可进一步细化为线程,是一个程序内部的一条执行路径。

    一个进程同一时间并行多个线程,多线程是程序有多个线程在同时执行,就是支持多线程的;

    线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。 

    进程是操作系统进行资源分配(包括cpu、内存、磁盘IO等)的最小单位

    线程是CPU调度和分配的基本单位(可以理解为CPU只能看到线程)

    线程作为调度和执行的单位,每个线程拥有独立的运行栈和程序计数器(pc),线程切换的开销小;

    一个进程中的多个线程共享相同的内存单元/内存地址空 ——>它们从同一个堆中分配对象,可以访问相同的变量和对象。这就使得线程间通信更简便、高效。但多个线程操作共享的系统资源可能就会来带安全的隐患

  4、扩展

     通过任务管理器查看进程:

          

    线程:

  线程调度:

    (1)分时调度

      所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间。

    (2) 抢占式调度

      优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个(线程随机性)Java使用的为抢占式调度 

      ① 设置线程的优先级

      

      ② 抢占式调度详解 

        大部分操作系统都支持多进程并发运行,现在的操作系统几乎都支持同时运行多个程序。例如打开电脑可以运行多个软件。。此时,这些程序是在同时运行,感觉这些软件好像在同一时刻运行着

        实际上,CPU(中央处理器)使用抢占式调度模式在多个线程间进行着高速的切换。对于CPU的一个核而言,某个时刻,只能执行一个线程,而 CPU的在多个线程间切换速度相对我们的感觉要快,看上去就是在同一时刻运行。 其实,多线程程序并不能提高程序的运行速度,但能够提高程序运行效率,让CPU的使用率更高。

        

二、单核CPU 和 多核CPU的理解

  1、单核 CPU

    单核 CPU 其实是一种假的多线程,因为在一个时间单元内,也只能执行一个线程的任务。

    例如:虽然有多车道,但是收费站只有一个工作人员在收费,只有收了费才能通过,那么CPU就好比收费人员。如果有某个人不想交钱, 那么收费人员可以把他“挂起”(晾着他,等他想通了,准备好了钱,再去收费) 。 但是因为CPU时间单元特别短,因此感觉不出来。

  2、如果是多核的话,才能更好的发挥多线程的效率。(现在的服务器都是多核的)

  3、一个 Java 应用程序 java.exe,其实至少有三个线程:main() 主线程,gc() 垃圾回收线程,异常处理线程。当然如果发生异常,会影响主线程。

三、并行与并发

  并行:多个 CPU 同时执行多个任务。比如:多个人同时做不同的事。(指在同一时刻,有多条指令(线程)在多个处理器(cpu上多个核)上同时执行,并行在多处理器系统中存在)

  并发:一个 CPU(采用时间片)同时执行多个任务。比如:秒杀、多个人做同一件事情;指在同一时刻只能有一条指令执行,但多个进程指令被快速的轮换执行,使得在宏观上具有多个进程同时执行的效果,但在微观上并不是同时执行的,只是把时间分成若干段,使多个进程快速交替的执行,并发可以在单处理器和多处理器系统中都存在。

   在操作系统中,安装了多个程序,并发指的是在一段时间内宏观上有多个程序同时运行,这在单 CPU 系统中,每一时刻只能有一道程序执行,即微观上这些程序是分时的交替运行,只不过是给人的感觉是同时运行,那是因为分时交替运行的时间是非常短的。

   在多个 CPU 系统中,这些可以并发执行的程序便可以分配到多个处理器上(CPU),实现多任务并行执行,即利用每个处理器来处理一个可以并发执行的程序,这样多个程序便可以同时执行。

   对于多核 CPU,便是多核处理器,核越多,并行处理的程序越多,能大大的提高电脑运行的效率。

   注意单核处理器的计算机肯定是不能并行的处理多个任务的,只能是多个任务在单个CPU上并发运行。同理,线程也是一样的,从宏观角度上理解线程是并行运行的,但是从微观角度上分析却是串行运行的,即一个线程一个线程的去运行,当系统只有一个CPU时,线程会以某种顺序执行多个线程,我们把这种情况称之为 线程调度。 

  

  CPU的多核和应用程序的多线程的关系

  多核就是系统同时可以运行多个线程,比如双核可以同时执行两个线程。单核只能一次执行一个线程

  规律

  • 单CPU中进程只能是并发,多CPU计算机中进程可以并行也可以并发。
  • 单CPU单核中线程只能并发,单CPU多核中线程可以并行也可以并发。
  • 无论是并发还是并行,使用者来看,看到的是多进程,多线程。

四、使用多线程的优点

  背景:以单核 CPU 为例,只使用单个线程先后完成多个任务(调用多个方法),肯定比用多个线程来完成用的时间更短,为何仍需要多线程呢?

  多线程的优点:

  1、提高应用程序的响应。对图形化界面更有意义,可增强用户体验。

  2、提高计算机系统 CPU 的利用率;

  3、改善程序结构。将既长又复杂的进程分为多个线程,独立运行,利于理解和修改;

五、何时需要多线程

    •  程序需要同时执行两个或多个任务;
    •    程序需要实现一些需要等待的任务时,如用户输入、文件读写操作、网络操作、搜索等;
    •    需要一些后台运行的程序时;

扩展:

几个关于CPU、线程执行的知识点

1、在单CPU计算机中,CPU是无法被多个程序并行使用的。

2、操作系统中存在一种调度器,它可以负责拆分CPU为一段段时间的运行片,轮流分配给不同的进程。

3、程序的运行不仅仅需要CPU,还需要很多其他资源,如内存啊,显卡啊,GPS啊,磁盘等等,这些统称为程序的执行环境,也就是程序上下文。

4、多个程序没办法同一个时间共享CPU,那怎么办呢?这个时候比进程更小的线程就出来了,通过在不同线程的切换来达到共享CPU、共享程序上下文的目的。

5、大家都知道,CPU有单核和多核区别,单核CPU其实就是多个线程会轮流得到那一个CPU核心的支持;在多核CPU中,一个核心可以服务于一个线程,例如我的电脑是4核的话,有四个线程A、B、C、D需要处理,那CPU会将他们分配到核心1、2、3、4,如果还有其他更多的线程,也必须要等待CPU的切换执行。

通过上面几个知识点,可以看出不管是在多核还是单核的系统中,CPU在多线程的环境中都是要不断切换线程来处理任务的,当然,CPU在切换任务时也不是顺便切换,而是根据一定的算法来调度、切换线程,一般有这样两种模式:分时调度和抢占式调度。

分时调度就是按照顺序平均分配;

抢占式调度就是按照优先级来进行分配。

对于多线程程序,单核cpu与多核cpu是怎么工作的

此文中的大部分资料来自于网络上,我只是觉得把有道理的整理一下,方便以后查阅。

1.多线程在单核和多核CPU上的执行效率问题的讨论
  a1: 多线程在单cpu中其实也是顺序执行的,不过系统可以帮你切换那个执行而已,其实并没有快(反而慢)多个cpu的话就可以在两个cpu中同时执行了..............

  a2: 单核CPU上运行的多线程程序, 同一时间只能一个线程在跑, 系统帮你切换线程而已, 系统给每个线程分配时间片来执行, 每个时间片大概10ms左右, 看起来像是同时跑, 但实际上是每个线程跑一点点就换到其它线程继续跑

  效率不会有提高的
  切换线程反倒会增加开销

  a3: #3楼说的是对的。所以一般没有必要的话,尤其在单核CPU的时候,不推荐使用多线程。
  单核CPU时使用多线程,通常是有线程要处于等待状态。
  而对于普通的进度条更新类的,能够简单控制的(比如:在循环里面手动处理消息)就简单控制,一般不使用线程,这样可以提高程序的性能。并且避免掉不必要的线程同步问题。

  a4: 你试一下双核三线程,保准效率反而比双线程低!

算法同样时,CPU占用率达到100%的最小线程数效率最高,如果是cpu占率率高的运算单核单线程,双核双线程,四核四线程是最适合的。

但为什么有时候线程数超过CPU内核数会更快呢?原因是这种程序的单个线程运算量不足以占满CPU一个内核(比如存在大量IO操作,IO比较慢,是程序瓶颈)。

  a5: 多线程的用处在于,做某个耗时的操作时,需要等待返回结果,这时用多线程可以提高程序并发程度。如果一个不需要任何等待并且顺序执行能够完成的任务,用多线程简直是浪费。

http://bbs.csdn.net/topics/320003381


2.浅谈多核CPU、多线程与并行计算

  a1: CPU发展趋势

核心数目依旧会越来越多,依据摩尔定律,由于单个核心性能提升有着严重的瓶颈问题,普通的桌面PC有望在2017年末2018年初达到24核心(或者16核32线程),我们如何来面对这突如其来的核心数目的增加?编程也要与时俱进。笔者斗胆预测,CPU各个核心之间的片内总线将会采用4路组相连:),因为全相连太过复杂,单总线又不够给力。而且应该是非对称多核处理器,可能其中会混杂几个DSP处理器或流处理器。

  a2: 线程越多越好吗?什么时候才有必要用多线程?

线程必然不是越多越好,线程切换也是要开销的,当你增加一个线程的时候,增加的额外开销要小于该线程能够消除的阻塞时间,这才叫物有所值。

Linux自从2.6内核开始,就会把不同的线程交给不同的核心去处理。Windows也从NT.4.0开始支持这一特性。

什么时候该使用多线程呢?这要分四种情况讨论:

  a.多核CPU——计算密集型任务。此时要尽量使用多线程,可以提高任务执行效率,例如加密解密,数据压缩解压缩(视频、音频、普通数据),否则只能使一个核心满载,而其他核心闲置。

  b.单核CPU——计算密集型任务。此时的任务已经把CPU资源100%消耗了,就没必要也不可能使用多线程来提高计算效率了;相反,如果要做人机交互,最好还是要用多线程,避免用户没法对计算机进行操作。

  c.单核CPU——IO密集型任务,使用多线程还是为了人机交互方便,

  d.多核CPU——IO密集型任务,这就更不用说了,跟单核时候原因一样。

4.程序员需要掌握的技巧/技术

(1)减少串行化的代码用以提高效率。这是废话。

(2)单一的共享数据分布化:把一个数据复制很多份,让不同线程可以同时访问。

(3)负载均衡,分为静态的和动态的两种。具体的参见有关文献。

http://www.linuxidc.com/Linux/2015-02/113734.htm


3.请问:CPU的多核和应用程序的多线程的关系是怎么样的?
a1: 多核儿就是系统同时可以运行多个线程,比如双核可以同时执行两个线程。单核儿只能一次执行一个线程。

a2: 试了一个ping 从192.168.0.1 到192.169.0.255的程序
用多线程做的,发现在单核的机器上和多核的机器运行性能有两倍左右的差异。

a3: 多核对于用户,应该说对于程序员来说,是透明的,根本不用管它,当你是单核的编程就可以了,除非使用OpenMP进行编程,就用很多条条框框了,另外你上面的测试是不准确的,网络(主要是远程主机)会因为不同时候而有不同的响应速度,你应该在干净的本机同环境下进行测试.但是,对于多线程多核优于单核还是可以确定的. 总之,我们不用担心程序在单核或多核上会出现并发问题.

a4: 多核指的是CPU有多个核心,多线程是程序有多个线程在同时执行。
多核也要用多线程才能发挥优势。
同样,多线程要在多核上才能真正有优势。
这点来说,对程序员不是透明的。程序员可以控制程序/线程在哪个CPU(核)上运行。用户也可以控制程序在哪几个核上运行。所以多核,多线程对用户和程序员都不是透明的。程序员必须了解这方面的知识。才能让程序最大限度的发挥机器的性能。

http://bbs.csdn.net/topics/120075600


4.pthread
php手册中关于pthread有关函数: http://php.net/manual/en/book.pthreads.php
pthread扩展:http://pecl.php.net/package/pthreads

http://www.baidu.com/s?wd=php%20pthread
http://www.sogou.com/web?query=php%20pthread
http://www.sogou.com/web?query=php%20pthread

延伸阅读:
http://www.baidu.com/s?wd=多线程程序%20单核cpu%20多核cpu
http://www.sogou.com/web?query=多线程程序%20单核cpu%20多核cpu
http://www.sogou.com/web?query=多线程程序%20单核cpu%20多核cpu
[转]浅谈多核CPU、多线程与并行计算: http://www.cnblogs.com/lihaozy/archive/2013/03/13/2957520.html
PHP使用Pthread实现的多线程操作实例: http://www.jb51.net/article/74849.htm
php三种实现多线程类似的方法: http://www.jb51.net/article/74165.htm

原文地址:https://www.cnblogs.com/niujifei/p/14401240.html