在很久很久以前,那时的计算机还没有操作系统这种东西,所以只能有一个程序,从头到尾地跑。于是这个程序要负责使用所有的资源,还得响应外部请求。想想这个程序得多复杂啊——为了做成一件事,可能要先把内存啊、IO啊这些外缘的东西搞定,而且在做事的时候还不能及时响应用户的请求。同时,由于这个程序一次只能做同一件事情,在某种程度上相当于浪费了宝贵的计算机资源。

于是,大神们发明了操作系统。在操作系统中,许多进程可以同时执行,操作系统给它们提供可以共享的资源——内存,file handle,以及安全凭证等。这样就可以提升运行的效率了,因为不同进程可以各自去做一些独立的事情,访问相关的系统资源;同时,由于可以使用不同的进程去解决不同的问题,也给程序员编程带来了便利。

在早期的操作系统中,每个进程都是一个虚拟的冯·诺依曼结构,程序中的指令是被顺序执行的,也就是说程序的控制流在程序执行之前就是确定的。这个串行执行的模型听起来非常简单,但是过了一段时间以后人们不禁开始思考:这是最好的做法吗?

在人类的日常生活中,经常需要“同时”去处理许多事情,比如做早饭时,把壶架在火上开始烧水,同时把吐司放进烤面包机,然后开始刷牙、洗脸,直到水烧开、面包烤好……人类很聪明,不会站在那里等待水烧开才去烤面包,因为这样做不仅水会凉,更主要的是会浪费时间。把水壶放在灶上,利用烧水的时间去做别的事,而水烧开时,水壶会自动发出声音提醒你水已经烧好了,这个过程在计算机的消息通信机制中有个术语,叫做“异步”。相反,一直站在那里等水烧开了才去做下一步的事情,叫做“同步”。高效的程序需要在串行和异步之间寻找一个平衡。

基于这种“同时做好几件事”的考虑,大神们把进程的发明更进一步,创造了线程。同一个进程中的线程可以共享内存和file handle等资源,但每个线程还有自己的program counter, 栈和局部变量等。这就相当于把进程带来的并行性又增强到一个更细的粒度。多线程的一个显著的优势在于高效的资源利用——在许多操作系统中,线程是最小的调度单位。多个线程可以同时被分配到多个CPU上被执行。几乎可以说,在多核系统上,不使用多线程是对系统资源的一种浪费。

除此之外,如果一个程序中有大量的不同性质的任务要做,我们可以把他们划分到不同的线程中进行处理,使它们成为各自独立的任务,这样大大降低了编程的难度。多线程的存在也大大提升了程序UI的响应度。在UI系统中,设置一个分发线程去听取用户的请求,收到请求后交给其他线程去做复杂的操作和处理,比用单线程进行处理好很多。如果在单线程UI中进行复杂的长时间操作,会让整个UI失去反应,而且无法取消当前的操作。

当然,多线程也为程序员带来了许多挑战。其中最大的挑战是,程序员需要努力不使自己的程序出现线程安全问题。 拿Java举例,如果多个线程同时访问某个数据,且访问时没有足够的同步机制,会导致一种叫做race condition的现象,即程序的运行结果与多线程被调度的时间先后顺序有关,这是我们不希望出现的——我们希望在前置条件一定的情况下,每次运行的结果都是相同的。比如单例模式中,某个类必须最多只有一个对象产生。

另外,多线程程序比单线程程序容易出现liveness问题,比如死锁。多线程的调度和上下文切换也是有代价的,会造成一些额外的性能开销。那么我们在什么情况下才去使用多线程,怎么去规避这些问题呢?这就是本书作者们会贯彻全书给我们讲解的问题。

[JCIP笔记] (一)多线程的起源的更多相关文章

  1. 孙鑫VC学习笔记:多线程编程

    孙鑫VC学习笔记:多线程编程 SkySeraph Dec 11st 2010  HQU Email:zgzhaobo@gmail.com    QQ:452728574 Latest Modified ...

  2. Python 爬虫笔记、多线程、xml解析、基础笔记(不定时更新)

    1  Python学习网址:http://www.runoob.com/python/python-multithreading.html

  3. [JCIP笔记] (二)当我们谈线程安全时,我们在谈论什么

    总听组里几个大神说起线程安全问题.本来对"线程安全"这个定义拿捏得就不是很准,更令人困惑的是,大神们用这个词指代的对象不仅抽象而且千变万化.比如,我们的架构师昨天说: " ...

  4. [JCIP笔记](四)踩在巨人的肩上

    读完第三章那些繁琐的术语和细节,头疼了整整一个星期.作者简直是苦口婆心,说得我如做梦一般.然而进入第四章,难度骤然降低,仿佛坐杭州的过山公交车突然下坡,鸟鸣花香扑面而来,看到了一片西湖美景. 从开始看 ...

  5. [心得笔记]Java多线程中的内存模型

    一:现代计算机的高速缓存 在计算机组成原理中讲到,现代计算机为了匹配 计算机存储设备的读写速度 与  处理器运算速度,在CPU和内存设备之间加入了一个名为Cache的高速缓存设备来作为缓冲:将运算需要 ...

  6. JUC学习笔记--Thread多线程基础

    实现多线程的两种方法 java 实现多线程通过两种方式1.继承Thread类 ,2.实现Runnable接口 class Newthead extends Thread{ public void ru ...

  7. Android应用开发学习笔记之多线程与Handler消息处理机制

    作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz 和JAVA一样,Android下我们可以通过创建一个Thread对象实现多线程.Thread类有多个构造函数,一般通 ...

  8. 毕向东udp学习笔记3多线程聊天

    项目功能: 实现了多线程下的发送接收,比较好 希望可以加入GUI,类似聊天软件一样,有一个消息输入框,捕获输入消息,作为发送线程 有一个显示消息框,接收消息并显示,作为接收线程 不知道的是,当在线程中 ...

  9. [JCIP笔记] (三)如何设计一个线程安全的对象

    在当我们谈论线程安全时,我们在谈论什么中,我们讨论了怎样通过Java的synchronize机制去避免几个线程同时访问一个变量时发生问题.忧国忧民的Brian Goetz大神在多年的开发过程中,也悟到 ...

随机推荐

  1. [DeeplearningAI笔记]改善深层神经网络_深度学习的实用层面1.10_1.12/梯度消失/梯度爆炸/权重初始化

    觉得有用的话,欢迎一起讨论相互学习~Follow Me 1.10 梯度消失和梯度爆炸 当训练神经网络,尤其是深度神经网络时,经常会出现的问题是梯度消失或者梯度爆炸,也就是说当你训练深度网络时,导数或坡 ...

  2. 浅谈WPF依赖项属性

    浅谈WPF依赖项属性 0. 引言 依赖项属性虽然在使用上和CLR属性一样,但是它是WPF特有的,不同于CLR属性.只是封装为我们常用CLR的属性,在语法使用上和CLR属性一样.WPF中一些功能:动画, ...

  3. Android逆向之so的半自动化逆向

    因为工作需要,转型干android逆向,有几个月了.不过对于so的逆向,任然停留在,难难难的阶段,虽然上次自己还是逆向了一个15k左右的小so文件,但是,那个基本是靠,一步一步跟代码,查看堆栈信息来自 ...

  4. 在.NetCore中使用Myrmec检测文件真实格式

    Myrmec 是什么? Myrmec 是一个用于检测文件格式的库,Myrmec不同于其它库或者手写检测代码,Myrmec不依赖文件扩展名(在实际使用中,你的用户很可能使用虚假的扩展名欺骗你的应用程序) ...

  5. 使用原生JS定位网页元素

    约定:1.<meta name="viewport" content="width=device-width">这种标记简称"wdw&qu ...

  6. ASP.NET Core 发布 centos7 配置守护进程

    ASP.NET Core应用程序发布linux在shell中运行是正常的.可一但shell关闭网站也就关闭了,所以要配置守护进程, 用的是Supervisor,本文主要记录配置的过程和过程遇到的问题 ...

  7. ACE在windows下的编译及配置(VS2010)

    ACE在windows下的编译及配置(VS2010) 分类:             -[小西南]-              2013-08-06 16:17     2354人阅读     评论( ...

  8. supervisor配置文件详解

    介绍 Supervisor是一个进程控制系统. 它是一个C/S系统(注意: 其提供WEB接口给用户查询和控制), 它允许用户去监控和控制在类UNIX系统的进程. 它的目标与launchd, daemo ...

  9. python学习:99乘法口诀

    #!/usr/bin/python   for i in xrange(1,10):     for j in xrange(1,i+1):         print "%s*%s=%s& ...

  10. Redis 实践2-数据结构

    alias redis-cli='/usr/local/redis/bin/redis-cli'   vi .bashrc 编辑加入  alias redis-cli='/usr/local/redi ...