转载自海子:http://www.cnblogs.com/dolphin0520/p/3910667.html

Java多线程基础:进程和线程之由来

  在前面,已经介绍了Java的基础知识,现在我们来讨论一点稍微难一点的问题:Java并发编程。当然,Java并发编程涉及到很多方面的内容,不是一朝一夕就能够融会贯通使用的,需要在实践中不断积累。由于并发肯定涉及到多线程,因此在进入并发编程主题之前,我们先来了解一下进程和线程的由来,这对后面对并发编程的理解将会有很大的帮助。

  下面是本文的目录大纲:

  一.操作系统中为什么会出现进程?

  二.为什么会出现线程?

  三.多线程并发

  若有不正之处,请多多谅解并欢迎指正。

  请尊重作者劳动成果,转载请标明原文地址:

  http://www.cnblogs.com/dolphin0520/p/3910667.html

一.操作系统中为什么会出现进程?

  说起进程的由来,我们需要从操作系统的发展历史谈起。

  也许在今天,我们无法想象在很多年以前计算机是什么样子。我们现在可以用计算机来做很多事情:办公、娱乐、上网,但是在计算机刚出现的时候,是为了解决数学计算的问题,因为很多大量的计算通过人力去完成是很耗时间和人力成本的。在最初的时候,计算机只能接受一些特定的指令,用户输入一个指令,计算机就做一个操作。当用户在思考或者输入数据时,计算机就在等待。显然这样效率和很低下,因为很多时候,计算机处于等待用户输入的状态。

  那么能不能把一系列需要操作的指令预先写下来,形成一个清单,然后一次性交给计算机,计算机不断地去读取指令来进行相应的操作?就这样,批处理操作系统诞生了。用户可以将需要执行的多个程序写在磁带上,然后交由计算机去读取并逐个地执行这些程序,并将输出结果写到另一个磁带上。

  虽然批处理操作系统的诞生极大地提高了任务处理的便捷性,但是仍然存在一个很大的问题:

  假如有两个任务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,对于解压文件来说,多线程肯定优于单线程,因为多个线程能够更加充分利用每个核的资源。

  虽然多线程能够提升程序性能,但是相对于单线程来说,它的编程要复杂地多,要考虑线程安全问题。因此,在实际编程过程中,要根据实际情况具体选择。

  关于进程和线程的由来,暂时就讲这么多了,感兴趣的朋友可以参考相关资料。

转载于:https://www.cnblogs.com/snowwhite/p/4651465.html

Java并发编程:进程和线程之由来__进程让操作系统的并发性成为可能,而线程让进程的内部并发成为可能...相关推荐

  1. 《JUC并发编程 - 高级篇》03 - 共享对象之管程 下篇(Monitor | waitnotify | ParkUnpark | 线程状态转换 | 活跃性 | ReentrantLock)

  2. Java并发编程(01):线程的创建方式,状态周期管理

    本文源码:GitHub·点这里 || GitEE·点这里 一.并发编程简介 1.基础概念 程序 与计算机系统操作有关的计算机程序.规程.规则,以及可能有的文件.文档及数据. 进程 进程是计算机中的程序 ...

  3. 【从入门到放弃-Java】并发编程-线程安全

    概述 并发编程,即多条线程在同一时间段内"同时"运行. 在多处理器系统已经普及的今天,多线程能发挥出其优势,如:一个8核cpu的服务器,如果只使用单线程的话,将有7个处理器被闲置, ...

  4. Java并发编程的艺术_Conc

    Java并发编程的艺术 1 并发编程的挑战 1.1 上下文切换 即使是单核处理器也支持多线程执行代码,CPU通过给每个线程分配CPU时间片来实现这个机制.时间片是CPU分配给各个线程的时间,因为时间片 ...

  5. Java开发中遇到具有挑战的事_Java并发编程的挑战:遇到的问题及如何解决

    并发编程的目的是为了让程序运行得更快,但是,并不是启动更多的线程就能让程序最大限度地并发执行.在进行并发编程时,如果希望通过多线程执行任务让程序运行得更快,会面临非常多的挑战,比如上下文切换的问题.死 ...

  6. Java并发编程实战_[Java并发编程实战] 简介

    并发简史 在早期不包含操作系统的计算机中,程序都是单一的串行程序,从头至尾只能执行一个程序,并且这个程序访问这个计算机的所有资源.然而,随着技术的发展,操作系统出现了.它使得计算机程序有了进程,线程的 ...

  7. [Java并发编程实战] 简介

    并发简史 在早期不包含操作系统的计算机中,程序都是单一的串行程序,从头至尾只能执行一个程序,并且这个程序访问这个计算机的所有资源.然而,随着技术的发展,操作系统出现了.它使得计算机程序有了进程,线程的 ...

  8. # Java 并发编程的艺术(二)

    Java 并发编程的艺术(二) 文章目录 Java 并发编程的艺术(二) 并发编程的挑战 上下文切换 如何减少上下文的切换 死锁 资源限制的挑战 Java 并发机制的底层实现原理 volatile 的 ...

  9. 【读书笔记】Java并发编程的艺术

    第一章 并发编程的挑战 上下文切换 上下文切换概述 切出:一个线程被剥夺处理器的使用权而暂定运行 切入:一个线程被选中占用处理器或者继续运行 上下文:在这种切入切出的过程中,操作系统需要保存和恢复相应 ...

  10. Java并发编程一万字总结(吐血整理)

    文章目录 并发编程简介 使用并发编程的优势 1.充分利用多核CPU的处理能力 2.方便业务建模 并发编程带来的风险 1.安全性问题 2.活跃性问题 3.性能问题 创建线程的几种方法 实现Runnabl ...

最新文章

  1. 关于二叉树的链表表示的一个问题
  2. C++种子点搜索算法之线扫描方法的实现
  3. python爬取音乐并保存_python3 实现爬取TOP500的音乐信息并存储到mongoDB数据库中
  4. 您与此网站建立的连接不安全_dede网站密码忘记找回服务为先
  5. Swift学习之UI开发初探
  6. 开机、问题-MocorDroid拔掉电池开机比正常关机后开机慢1分钟问题-by小雨
  7. jieba安装_Jieba库实现词性标注及小说人物角色抽取
  8. 【转】Maven 手动添加 JAR 包到本地仓库
  9. 开源容器云openshift pdf_OpenShift和Kubernetes的10个最重要的区别
  10. 看故事也能长知识,CPU的工作原理原来这么简单!
  11. 【生信】统计学基础知识
  12. VMware ESXi 安装
  13. 街头篮球服务器维护,《街头篮球》4月23日新版活动抢先看
  14. 中国软件公司排名(北京)(杭州)
  15. golang 自定义日志
  16. 二维列表python
  17. mysql搜索结果去重_mysql数据库去重查询
  18. 洋洋洒洒688字带你彻底吃透Zuul的插件机制及定制化开发
  19. 进阶博弈论 Advanced Game Theory (Stanford+UBC)学习笔记
  20. 第1章 计算机网络和因特网-计算机网络

热门文章

  1. iOS开发经验总结(一)
  2. SVN服务设置提交时备注文字长度
  3. PHP下载文件(隐藏真实的下载地址)
  4. delphi操作word
  5. 电商金额计算的 4 个坑,千万注意了!
  6. 拜托!你只会用 ! = null 判空?
  7. 有了这个王座,写代码的速度都加快了
  8. Spring 事务的那些坑,都在这里了!
  9. 面试常被问的65个问题及回答技巧(请收藏)
  10. 一名 IT 经理是如何把项目带崩的?