在很久很久以前,那时的计算机还没有操作系统这种东西,所以只能有一个程序,从头到尾地跑。于是这个程序要负责使用所有的资源,还得响应外部请求。想想这个程序得多复杂啊——为了做成一件事,可能要先把内存啊、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. GO开发:用go写个日志监控系统

    日志收集系统架构 1.项目背景 a. 每个系统都有日志,当系统出现问题时,需要通过日志解决问题 b. 当系统机器比较少时,登陆到服务器上查看即可满足 c. 当系统机器规模巨大,登陆到机器上查看几乎不现 ...

  2. Asp.net mvc 中View 的呈现(二)

    [toc] 上一节介绍了 Asp.net mvc 中除 ViewResult 外的所有的 ActionResult,这一节介绍 ViewResult. ViewResultBase ViewResul ...

  3. VUE 框架

    一.什么是vue             它是一个构建用户界面的JAVASCRITPO框架 二.怎么使用VUE (1).引入vue.js 如:<script src='vue.js'>&l ...

  4. Jmeter3.1 使用技巧

    一.JMeter官网 下载地址 http://jmeter.apache.org/download_jmeter.cgi Jmeter wiki https://wiki.apache.org/jme ...

  5. ABP官方文档翻译 3.8 数据过滤器

    数据过滤器 介绍 预定义过滤器 ISoftDelete 何时使用? IMustHaveTenant 何时使用? IMayHaveTenant 何时使用 禁用过滤器 关于using语句 关于多租户 全局 ...

  6. SDN第五次上机作业

    作业链接 1.建立拓扑,并连接上ODL控制器. 2.利用ODL下发组表.流表,实现建议负载均衡 查看s2接收的数据包都被drop掉了 在s1中下发组表 在s1中下发流表使组表生效 下发流表覆盖S2中d ...

  7. selenium headlesschrome下设置最大窗口模式

    做微博登录的时候,用selenium的chrome界面模式,可以用下面方式显示最大窗口: from selenium.webdriver.chrome.options import Options c ...

  8. 【linux之正则表达式】

    一.grep grep家族grep.egrep.fgrepGlobally search a Regular Expression and Print根据我们提供的模式进行查找,并且将文件中匹配的行显 ...

  9. 在linux内核中实现自己的系统调用

    如实现一个简单的打印:printk 1.cd linux-ok6410/kernel/ vim printk.cvoid sys_pk(){printk("<0>this is ...

  10. 【笔记】h5 页面唤起电话呼叫

    参考文章:https://www.cnblogs.com/lilin1995/p/5640684.html 最近完成一个公司的官网移动端页面,涉及到了唤起电话这个功能,说实在js 并没有为此提供 ap ...