Java并发编程(一):进程和线程之由来
转自:http://www.cnblogs.com/dolphin0520/p/3910667.html
在前面,已经介绍了Java的基础知识,现在我们来讨论一点稍微难一点的问题:Java并发编程。当然,Java并发编程涉及到很多方面的内容,不是一朝一夕就能够融会贯通使用的,需要在实践中不断积累。由于并发肯定涉及到多线程,因此在进入并发编程主题之前,我们先来了解一下进程和线程的由来,这对后面对并发编程的理解将会有很大的帮助。
下面是本文的目录大纲:
一.操作系统中为什么会出现进程?
二.为什么会出现线程?
三.多线程并发
一.操作系统中为什么会出现进程?
说起进程的由来,我们需要从操作系统的发展历史谈起。
也许在今天,我们无法想象在很多年以前计算机是什么样子。我们现在可以用计算机来做很多事情:办公、娱乐、上网,但是在计算机刚出现的时候,是为了解决数学计算的问题,因为很多大量的计算通过人力去完成是很耗时间和人力成本的。在最初的时候,计算机只能接受一些特定的指令,用户输入一个指令,计算机就做一个操作。当用户在思考或者输入数据时,计算机就在等待。显然这样效率和很低下,因为很多时候,计算机处于等待用户输入的状态。
那么能不能把一系列需要操作的指令预先写下来,形成一个清单,然后一次性交给计算机,计算机不断地去读取指令来进行相应的操作?就这样,批处理操作系统诞生了。用户可以将需要执行的多个程序写在磁带上,然后交由计算机去读取并逐个地执行这些程序,并将输出结果写到另一个磁带上。
虽然批处理操作系统的诞生极大地提高了任务处理的便捷性,但是仍然存在一个很大的问题:
假如有两个任务A和B,任务A在执行到一半的过程中,需要读取大量的数据输入(I/O操作),而此时CPU只能静静地等待任务A读取完数据才能继续执行,这样就白白浪费了CPU资源。人们于是想,能否在任务A读取数据的过程中,让任务B去执行,当任务A读取完数据之后,让任务B暂停,然后让任务A继续执行?
但是这样就有一个问题,原来每次都是一个程序在计算机里面运行,也就说内存中始终只有一个程序的运行数据。而如果想要任务A执行I/O操作的时候,让任务B去执行,必然内存中要装入多个程序,那么如何处理呢?多个程序使用的数据如何进行辨别呢?并且当一个程序运行暂停后,后面如何恢复到它之前执行的状态呢?
这个时候人们就发明了进程,用进程来对应一个程序,每个进程对应一定的内存地址空间,并且只能使用它自己的内存空间,各个进程间互不干扰。并且进程保存了程序每个时刻的运行状态,这样就为进程切换提供了可能。当进程暂时时,它会保存当前进程的状态(比如进程标识、进程的使用的资源等),在下一次重新切换回来时,便根据之前保存的状态进行恢复,然后继续执行。
这就是并发,能够让操作系统从宏观上看起来同一个时间段有多个任务在执行。换句话说,进程让操作系统的并发成为了可能。
注意,虽然并发从宏观上看有多个任务在执行,但是事实上,任一个具体的时刻,只有一个任务在占用CPU资源(当然是对于单核CPU来说的)。
二.为什么会出现线程?
在出现了进程之后,操作系统的性能得到了大大的提升。虽然进程的出现解决了操作系统的并发问题,但是人们仍然不满足,人们逐渐对实时性有了要求。因为一个进程在一个时间段内只能做一件事情,如果一个进程有多个子任务,只能逐个地去执行这些子任务。比如对于一个监控系统来说,它不仅要把图像数据显示在画面上,还要与服务端进行通信获取图像数据,还要处理人们的交互操作。如果某一个时刻该系统正在与服务器通信获取图像数据,而用户又在监控系统上点击了某个按钮,那么该系统就要等待获取完图像数据之后才能处理用户的操作,如果获取图像数据需要耗费10s,那么用户就只有一直在等待。显然,对于这样的系统,人们是无法满足的。
那么可不可以将这些子任务分开执行呢?即在系统获取图像数据的同时,如果用户点击了某个按钮,则会暂停获取图像数据,而先去响应用户的操作(因为用户的操作往往执行时间很短),在处理完用户操作之后,再继续获取图像数据。人们就发明了线程,让一个线程去执行一个子任务,这样一个进程就包括了多个线程,每个线程负责一个独立的子任务,这样在用户点击按钮的时候,就可以暂停获取图像数据的线程,让UI线程响应用户的操作,响应完之后再切换回来,让获取图像的线程得到CPU资源。从而让用户感觉系统是同时在做多件事情的,满足了用户对实时性的要求。
换句话说,进程让操作系统的并发性成为可能,而线程让进程的内部并发成为可能。
但是要注意,一个进程虽然包括多个线程,但是这些线程是共同享有进程占有的资源和地址空间的。进程是操作系统进行资源分配的基本单位,而线程是操作系统进行调度的基本单位。
三.多线程并发
由于多个线程是共同占有所属进程的资源和地址空间的,那么就会存在一个问题:
如果多个线程要同时访问某个资源,怎么处理?
这个问题就是后序文章中要重点讲述的同步问题。
那么可能有朋友会问,现在很多时候都采用多线程编程,那么是不是多线程的性能一定就由于单线程呢?
不一定,要看具体的任务以及计算机的配置。比如说:
对于单核CPU,如果是CPU密集型任务,如解压文件,多线程的性能反而不如单线程性能,因为解压文件需要一直占用CPU资源,如果采用多线程,线程切换导致的开销反而会让性能下降。
但是对于比如交互类型的任务,肯定是需要使用多线程的、
而对于多核CPU,对于解压文件来说,多线程肯定优于单线程,因为多个线程能够更加充分利用每个核的资源。
虽然多线程能够提升程序性能,但是相对于单线程来说,它的编程要复杂地多,要考虑线程安全问题。因此,在实际编程过程中,要根据实际情况具体选择。
关于进程和线程的由来,暂时就讲这么多了,感兴趣的朋友可以参考相关资料。
Java并发编程(一):进程和线程之由来的更多相关文章
- Java并发编程:进程和线程之由来
Java多线程基础:进程和线程之由来 在前面,已经介绍了Java的基础知识,现在我们来讨论一点稍微难一点的问题:Java并发编程.当然,Java并发编程涉及到很多方面的内容,不是一朝一夕就能够融会贯通 ...
- Java并发编程:进程和线程之由来__进程让操作系统的并发性成为可能,而线程让进程的内部并发成为可能
转载自海子:http://www.cnblogs.com/dolphin0520/p/3910667.html Java多线程基础:进程和线程之由来 在前面,已经介绍了Java的基础知识,现在我们来讨 ...
- java并发编程:进程和线程
java并发编程涉及到很多内容,当然也包括多线程,再次补充点相关概念 原文地址:http://www.cnblogs.com/dolphin0520/p/3910667.html 一.操作系统中为什么 ...
- Java并发编程 | 从进程、线程到并发问题实例解决
计划写几篇文章讲述下Java并发编程,帮助一些初学者成体系的理解并发编程并实际使用,而不只是碎片化的了解一些Synchronized.ReentrantLock等技术点.在讲述的过程中,也想融入一些相 ...
- Java并发基础:进程和线程之由来
转载自:http://www.cnblogs.com/dolphin0520/p/3910667.html 在前面,已经介绍了Java的基础知识,现在我们来讨论一点稍微难一点的问题:Java并发编程. ...
- Java并发编程:如何创建线程?
Java并发编程:如何创建线程? 在前面一篇文章中已经讲述了在进程和线程的由来,今天就来讲一下在Java中如何创建线程,让线程去执行一个子任务.下面先讲述一下Java中的应用程序和进程相关的概念知识, ...
- 【转】Java并发编程:如何创建线程?
一.Java中关于应用程序和进程相关的概念 在Java中,一个应用程序对应着一个JVM实例(也有地方称为JVM进程),一般来说名字默认是java.exe或者javaw.exe(windows下可以通过 ...
- [Java并发编程(二)] 线程池 FixedThreadPool、CachedThreadPool、ForkJoinPool?为后台任务选择合适的 Java executors
[Java并发编程(二)] 线程池 FixedThreadPool.CachedThreadPool.ForkJoinPool?为后台任务选择合适的 Java executors ... 摘要 Jav ...
- 2、Java并发编程:如何创建线程
Java并发编程:如何创建线程? 在前面一篇文章中已经讲述了在进程和线程的由来,今天就来讲一下在Java中如何创建线程,让线程去执行一个子任务.下面先讲述一下Java中的应用程序和进程相关的概念知识, ...
- Java并发编程:进程的创建
Java并发编程:进程的创建 */--> code {color: #FF0000} pre.src {background-color: #002b36; color: #839496;} J ...
随机推荐
- Unity经典游戏教程之:弓之骑士
版权声明: 本文原创发布于博客园"优梦创客"的博客空间(网址:http://www.cnblogs.com/raymondking123/)以及微信公众号"优梦创客&qu ...
- java并发编程(十五)----(线程池)java线程池简介
好的软件设计不建议手动创建和销毁线程.线程的创建和销毁是非常耗 CPU 和内存的,因为这需要 JVM 和操作系统的参与.64位 JVM 默认线程栈是大小1 MB.这就是为什么说在请求频繁时为每个小的请 ...
- 关于Java虚拟机运行时数据区域的总结
Java虚拟机运行时数据区域 程序计数器(Program Counter) 程序计数器作为一个概念模型,这个是用来指示下一条需要执行的字节码指令在哪. Java的多线程实际上是通过线程轮转做到的,如果 ...
- 虚拟机安装CentOS的简短教程
说明: 为什么要学Linux?因为现在互联网产品普遍使用Linux作为服务器系统. 测试工程师要学Linux吗?要,因为你会需要跟服务器打交道. 什么情况下测试工程师会跟服务器打交道?你可能要去部署测 ...
- .netcore持续集成测试篇之测试方法改造
系列目录 通过前面两节讲解,我们的测试类中已经有两个测试方法了,总体上如下 public class mvc20 { private readonly HttpClient _client; publ ...
- 从头开始制作OJ-在线IDE的搭建
大家好,我是Fred913. 之前,我看过各种OJ(OpenJudge) 但是,还是没有自己做的好. 所以,我就来写了这篇教程. 环境 这次,我打算使用这些:PHP 5.6 Nginx/Apache ...
- #348 大陆争霸(DIjkstra)
在一个遥远的世界里有两个国家:位于大陆西端的杰森国和位于大陆东端的 克里斯国.两个国家的人民分别信仰两个对立的神:杰森国信仰象征黑暗和毁灭 的神曾·布拉泽,而克里斯国信仰象征光明和永恒的神斯普林·布拉 ...
- spring-boot-plus项目目录结构(六)
spring-boot-plus项目目录结构 目录结构 bin:启动/重启命令脚本目录 logs:部署后记录日志目录 assembly:maven打包配置文件目录 java:源代码目录 resourc ...
- 小白学Python(6)——python-pptx 添加图表
添加图表 以下代码在新演示文稿中添加单系列柱形图 from pptx import Presentation from pptx.chart.data import CategoryChartData ...
- 盘一盘 NIO (二)—— Channel解析
Channel是个啥? Channel,顾名思义,它就是一个通道.NIO中的所有IO都是从 Channel 开始的. Channel通道和流非常类似,主要有以下几点区别: 1.流是单向的,通道是双向的 ...