[JCIP笔记] (一)多线程的起源
在很久很久以前,那时的计算机还没有操作系统这种东西,所以只能有一个程序,从头到尾地跑。于是这个程序要负责使用所有的资源,还得响应外部请求。想想这个程序得多复杂啊——为了做成一件事,可能要先把内存啊、IO啊这些外缘的东西搞定,而且在做事的时候还不能及时响应用户的请求。同时,由于这个程序一次只能做同一件事情,在某种程度上相当于浪费了宝贵的计算机资源。
于是,大神们发明了操作系统。在操作系统中,许多进程可以同时执行,操作系统给它们提供可以共享的资源——内存,file handle,以及安全凭证等。这样就可以提升运行的效率了,因为不同进程可以各自去做一些独立的事情,访问相关的系统资源;同时,由于可以使用不同的进程去解决不同的问题,也给程序员编程带来了便利。
在早期的操作系统中,每个进程都是一个虚拟的冯·诺依曼结构,程序中的指令是被顺序执行的,也就是说程序的控制流在程序执行之前就是确定的。这个串行执行的模型听起来非常简单,但是过了一段时间以后人们不禁开始思考:这是最好的做法吗?
在人类的日常生活中,经常需要“同时”去处理许多事情,比如做早饭时,把壶架在火上开始烧水,同时把吐司放进烤面包机,然后开始刷牙、洗脸,直到水烧开、面包烤好……人类很聪明,不会站在那里等待水烧开才去烤面包,因为这样做不仅水会凉,更主要的是会浪费时间。把水壶放在灶上,利用烧水的时间去做别的事,而水烧开时,水壶会自动发出声音提醒你水已经烧好了,这个过程在计算机的消息通信机制中有个术语,叫做“异步”。相反,一直站在那里等水烧开了才去做下一步的事情,叫做“同步”。高效的程序需要在串行和异步之间寻找一个平衡。
基于这种“同时做好几件事”的考虑,大神们把进程的发明更进一步,创造了线程。同一个进程中的线程可以共享内存和file handle等资源,但每个线程还有自己的program counter, 栈和局部变量等。这就相当于把进程带来的并行性又增强到一个更细的粒度。多线程的一个显著的优势在于高效的资源利用——在许多操作系统中,线程是最小的调度单位。多个线程可以同时被分配到多个CPU上被执行。几乎可以说,在多核系统上,不使用多线程是对系统资源的一种浪费。
除此之外,如果一个程序中有大量的不同性质的任务要做,我们可以把他们划分到不同的线程中进行处理,使它们成为各自独立的任务,这样大大降低了编程的难度。多线程的存在也大大提升了程序UI的响应度。在UI系统中,设置一个分发线程去听取用户的请求,收到请求后交给其他线程去做复杂的操作和处理,比用单线程进行处理好很多。如果在单线程UI中进行复杂的长时间操作,会让整个UI失去反应,而且无法取消当前的操作。
当然,多线程也为程序员带来了许多挑战。其中最大的挑战是,程序员需要努力不使自己的程序出现线程安全问题。 拿Java举例,如果多个线程同时访问某个数据,且访问时没有足够的同步机制,会导致一种叫做race condition的现象,即程序的运行结果与多线程被调度的时间先后顺序有关,这是我们不希望出现的——我们希望在前置条件一定的情况下,每次运行的结果都是相同的。比如单例模式中,某个类必须最多只有一个对象产生。
另外,多线程程序比单线程程序容易出现liveness问题,比如死锁。多线程的调度和上下文切换也是有代价的,会造成一些额外的性能开销。那么我们在什么情况下才去使用多线程,怎么去规避这些问题呢?这就是本书作者们会贯彻全书给我们讲解的问题。
[JCIP笔记] (一)多线程的起源的更多相关文章
- 孙鑫VC学习笔记:多线程编程
孙鑫VC学习笔记:多线程编程 SkySeraph Dec 11st 2010 HQU Email:zgzhaobo@gmail.com QQ:452728574 Latest Modified ...
- Python 爬虫笔记、多线程、xml解析、基础笔记(不定时更新)
1 Python学习网址:http://www.runoob.com/python/python-multithreading.html
- [JCIP笔记] (二)当我们谈线程安全时,我们在谈论什么
总听组里几个大神说起线程安全问题.本来对"线程安全"这个定义拿捏得就不是很准,更令人困惑的是,大神们用这个词指代的对象不仅抽象而且千变万化.比如,我们的架构师昨天说: " ...
- [JCIP笔记](四)踩在巨人的肩上
读完第三章那些繁琐的术语和细节,头疼了整整一个星期.作者简直是苦口婆心,说得我如做梦一般.然而进入第四章,难度骤然降低,仿佛坐杭州的过山公交车突然下坡,鸟鸣花香扑面而来,看到了一片西湖美景. 从开始看 ...
- [心得笔记]Java多线程中的内存模型
一:现代计算机的高速缓存 在计算机组成原理中讲到,现代计算机为了匹配 计算机存储设备的读写速度 与 处理器运算速度,在CPU和内存设备之间加入了一个名为Cache的高速缓存设备来作为缓冲:将运算需要 ...
- JUC学习笔记--Thread多线程基础
实现多线程的两种方法 java 实现多线程通过两种方式1.继承Thread类 ,2.实现Runnable接口 class Newthead extends Thread{ public void ru ...
- Android应用开发学习笔记之多线程与Handler消息处理机制
作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz 和JAVA一样,Android下我们可以通过创建一个Thread对象实现多线程.Thread类有多个构造函数,一般通 ...
- 毕向东udp学习笔记3多线程聊天
项目功能: 实现了多线程下的发送接收,比较好 希望可以加入GUI,类似聊天软件一样,有一个消息输入框,捕获输入消息,作为发送线程 有一个显示消息框,接收消息并显示,作为接收线程 不知道的是,当在线程中 ...
- [JCIP笔记] (三)如何设计一个线程安全的对象
在当我们谈论线程安全时,我们在谈论什么中,我们讨论了怎样通过Java的synchronize机制去避免几个线程同时访问一个变量时发生问题.忧国忧民的Brian Goetz大神在多年的开发过程中,也悟到 ...
随机推荐
- 机器学习--kNN算法识别手写字母
本文主要是用kNN算法对字母图片进行特征提取,分类识别.内容如下: kNN算法及相关Python模块介绍 对字母图片进行特征提取 kNN算法实现 kNN算法分析 一.kNN算法介绍 K近邻(kNN,k ...
- 创建github仓库的gh-pages分支
用git symbolic-ref命令将当前工作分支由master切换到一个尚不存在的分支gh-pages. $ git symbolic-ref HEAD refs/heads/gh-pages 删 ...
- Hands-On Machine Learning with Scikit-Learn and TensorFlow---读书笔记
去年在北京参加了一次由O'Reilly和Cloudera联合举办的大数据会议Strata Data Conference,并有幸获得了O'Reilly出版的Hands-On Machine Learn ...
- CSS中的字体属性和文本属性
1.CSS字体的属性 font 简写,作用是把所有的针对字体的属性设置在一个声明中 font-family 设置字体系列 font-size 设置字体尺寸 font-style 设置字体风格,ital ...
- centos yum方式安装net-snmp v3
SNMPv3的安全报头采用用户安全模式(USM),其提供具有机密性和完整性的网络管理通信.机密性通过采用数据加密标准(DES)来提供.尽管 这一算法以脆弱性著称(由于它采用的是40位的密钥),但与明文 ...
- gitlab 操作指南
重置密码 https://docs.gitlab.com/ce/security/reset_root_password.html gitlab 一键安装 https://docs.gitlab.co ...
- HashMap实现分析
HashMap最基本的实现思想如下图所示,使用数组加链表的组合形式来完成数据的存储. Entry在数组中的位置是由key的hashcode决定的. 向一个数组长度为16,负载因子为0.75的HashM ...
- codechef Dynamic GCD [树链剖分 gcd]
Dynamic GCD 题意:一棵树,字词树链加,树链gcd 根据\(gcd(a,b)=gcd(a,a-b)\) 得到\(gcd(a_1, a_2, ..., a_i) = gcd(a_1, a_1- ...
- CodeChef Little Elephant and Mouses [DP]
https://www.codechef.com/problems/LEMOUSE 题意: 有一个n *m的网格.有一头大象,初始时在(1,1),要移动到(n,m),每次只能向右或者向下走.有些格子中 ...
- Kafka基本知识回顾及复制
Producers发布记录到集群,集群维护这些记录并且将记录分发给Consumers. 在Kafka中,最关键的抽象是topic.Producers发布记录到一个topic,Consumers订阅一个 ...