java多线程(一)-概述

最近这段在看java多线程编程方面的东西。因此特写了几篇文章,来总结和回顾一下本身所学习到的相关知识。由于水平有限,文章中总结不全面甚至理解错误的地方,欢迎读者指点批评。java

咱们平时所接触到的程序,都是顺序编程。
顺序编程的意思是,程序中的全部事物在任意时刻都只能执行一个步骤(包括那些代码当中的顺序结构,选择结构,循环结构),
顺序编程知足了咱们可以碰到的大部分问题,可是有些问题,仅仅依靠顺序编程是不够的,举个例子,一个带界面的音乐播放程序,在播放歌曲的同时也能及时的响应用户在界面上进行的的按键操做(好比点击 下一曲 按钮)。那么此时顺序编程就不合适了,由于这是须要两件同时执行的事情,若是采用顺序编程,为了及时响应按键操做,咱们须要在代码的不少地方都要加上检测按键状态的代码。而这种场景下就须要并发编程了。linux

并发编程 有不一样的实现方式。 好比 多进程模式,多线程模式等。
而最多见也最直接的就是 操做系统级别使用的进程,所谓 进程就是运行在它本身的地址空间内的自包容的程序。好比,能够在电脑上,同时并行进行几个不一样的任务,qq和人聊天,酷狗播放器播放音乐,而后浏览器下着文件,这就是三个不一样的进程,这三个进程彼此之间相互隔绝,不受其余进程影响。 git

而对于同一个进程,也能够采用多线程开发技术,使得一个程序内部多个线程能够并行运行。程序员

固然,对于单核cpu,咱们说计算机能在同一个时间点并行运行多进程或多线程。它们实际上都不是真正意义上的同一个时间点,只不过cpu切换速度极快,操做系统将cpu时间切片,分配给不一样的任务。虽然看起来每一个任务在执行过程当中都是有时运行有时中止,可是鉴于cpu执行的速度极高,因此在咱们使用者看来,那都是连续的,不间断的。这几个不一样的任务就像同时并行运行同样。github

而伴随着多核cpu的出现,几个核同时运行,这个时候,它们才有多是在真正的同一个时间点并行运行。编程


而多线程,由于会对相同的内存空间进行并发读写操做,因此它们更加复杂。
解释一下这句话,仍是 回到刚才举的那个例子,在一台电脑上,同时运行几个不一样的任务。qq和人聊天,酷狗播放器播放音乐,而后浏览器下着文件。咱们知道,不管什么程序,归根结底编译到了最底层,那就是0和1。由于cpu只认识0和1,若是把0和1转化为容易阅读的语言,那就是汇编语言。看过汇编的应该知道,相似 什么mov ax,bx 之类的语句都是直接操做寄存器或内存地址的。那么这个时候问题就来了,酷狗播放器,qq,浏览器这三个程序,编译到了汇编层次,那么也会直接操做寄存器和内存地址,那么为何他们这些程序之间不冲突呢?缘由就是由于 其实他们这个地址之类的,都是虚拟内存地址。酷狗播放器和qq编译成汇编语言以后,他们的内存地址都是虚拟的,因此哪怕这两个程序在汇编层面都操做同一个内存地址,也不会彼此冲突。这中间的功劳就是属于操做系统和cpu。操做系统在运行这两个进程时,会和cpu一块儿起做用,把他们的虚拟地址空间转换为实际的地址空间。其实说白了,就是 酷狗播放器,qq,浏览器在编写他们各自的代码的时候。根本不会考虑汇编层面上,寄存器,内存地址之类的问题。他们只须要写好本身程序自己的代码就好了。至于那些多个进程怎么运行之类的复杂问题的,上层开发的程序员们是不用关心的。浏览器

而多线程,他们归根到底仍是属于同一个进程,所以多个不一样线程仍是对于同一内存空间进行操做,因此多线程更复杂,更容易出问题。服务器

对于多进程,某个进程崩溃了,那么对其余进程 没啥影响,可是对于多线程,某个线程崩溃了,它所属的这个进程也会受到直接影响。网络

固然,咱们在说不一样的进程在运行的时候,都属于各自干好本身的事情,中间不会发生什么联系。这样就避免了相互干扰。不过操做系统固然也提供了进程间通讯机制(IPC),好比linux的 管道,信号,套接字之类的。多线程

 

而从表面上看,若是一样一个任务(进程),分解成多个线程来执行,和单独一个线程来执行,理论上前者的开销应该是更大的,缘由很简单,执行多线程会增长 上下文切换的代价。可是实际上,多线程之因此更快,有两个主要因素。
(1)阻塞。程序由于程序控制以外的某些因素(好比I/0)而致使不能继续执行,cpu是如此宝贵的资源,若是cpu一直处于等待状态,那岂不是一种很大的浪费。拿i/o操做来讲,cpu的执行速度极高,它的时间都是按照纳秒为单位的,可是执行程序所须要的资源或数据确每每在内存,硬盘,乃至网络服务器上,它们的速度相对于cpu那就太慢,甚至极慢。若是是顺序编程,在这种状况下,cpu只能干等着,没办法继续干活。那么这种状况下,多线程就变的颇有必要了。此时cpu能够切换执行另外一个任务,那么就不用干等着其中一个线程。

(2)多核cpu的出现,在最初的时候cpu都是单核的,可是到如今四核八核都很广泛的状况下,若是是顺序编程只能在某一个核上运行。找人完成一件任务,一我的单独干,和8我的协助干,虽而后者会须要花费更多的组织和协调的耗费,可是明显后者干活比前者快。

多线程编程将一个大的程序(任务/进程)划分为多个分离的,独立运行的线程(子任务),一个线程就是该进程中的 一个单一的顺序控制流,每一个线程虽然没有独立的地址空间(由于只有进程才有),可是各个线程有本身的堆栈和局部变量。而在线程自己来看,就像它单独占有cpu同样。虽然底层机制是操做系统切分了cpu的时间,给它分配了这一段的时间。不过上层开发的程序员是不用关心这些的,因此这种线程模型方便了上层开发者。

 

-------
做者: www.yaoxiaowen.com
github: https://github.com/yaowen369

相关文章
相关标签/搜索