Java并发编程之背景知识

码途逐光者
• 阅读 2203

操作系统发展回顾


裸机

老早之前的计算机只有一个处理器,而一个处理器在同一时刻只能处理一条指令,换句话说,我们的代码需要一行一行的按顺序被计算机执行,计算机只能把一个程序完整的执行完,然后再执行第二个程序。所以计算机专业的同学们要排队去机房做实验,一个人执行完然他的程序后,第二个人再执行自己的程序,这也就意味着所有计算机资源是被一个程序独占的,计算机资源包括处理器、内存、硬盘、输入/输出设备啥的。这样的计算机系统我们称之为裸机。


简单批处理系统

后来人们发现对于价格高昂的计算机设备来说,在换人的过程中就浪费了好多时间,时间就是金钱,有这些时间可以多执行好多程序了。所以有人写了一个程序,把所有同学们需要做实验的程序都放在这个程序里排个队,由这个程序来协调各个同学们的程序执行,一个执行完了立即换成另一个,这样就不用人工干预了,所以他们把这样的系统叫做简单批处理系统,而那个负责协调各个童鞋们程序的程序,就是所谓的操作系统的雏形。


多道批处理系统

我们知道,处理器的速度是嗖嗖的,比内存访问的速度快好多个数量级,而内存又比硬盘、打印机等I/O设备啥的快好多个数量级,而程序执行过程中又免不了从硬盘里读个文件,往打印机输出个啥的,所以处理器浪费了好多时间等待这些I/O操作的完成。再一次,时间就是金钱,为了尽可能的剥削计算机的运算能力,在程序遇到I/O操作或者什么其他会阻塞程序执行的操作时,处理器会转向执行其它的程序,什么时候这个阻塞的操作完成了,再掉过头继续执行它。从宏观上看,处理器可以各个程序轮流执行,所以这样的系统就称为多道批处理系统。


分时处理

有的同学对排队执行程序这个事儿很有意见,大家都是学生,凭啥先执行你的后执行我的,你要是写了个while(true),那大家都得玩儿完~所以人们给每个程序都分配一点处理器时间去轮流执行,每个程序分配到的执行时间就叫做时间片,这个过程也叫做分时处理。又因为处理器速度太快了,时间片的大小可以做到微秒毫秒的大小,所以这个切换的过程对于人来说根本感觉不出来,所以看起来像各个程序在同时执行。不过后来人们在一台计算机上又装了多个处理器,就是我们常听说的4核、8核啥的,所以也可能真正的在同时执行。

而时间片具体设置为多大,处理器怎么切换各个程序的执行,这些工作就是所谓的操作系统来控制的。


进程

进程的概念和特点

我们自己写的程序,也就是所谓的用户程序是由操作系统来管理的,人们把一个执行着的程序叫做一个进程(英文名:Process),每个进程都有这么两个特点:

1.资源所有权

程序在运行过程中需要一定的资源,比如内存、I/O啥的,这些东西不能在不同进程间共享,假如一个进程占了另一个进程的内存,那另一个进程的数据不就丢失了么;一个进程正在使用打印机输出东西,另一个进程也使用的话,不就尴尬了么。所以进程所拥有的这些资源是不能共享的,而这种资源分配的活是由操作系统来管理的。

2.调度/执行

操作系统会为它管理的进程分配时间片,来调度哪个进程应该被处理器处理,哪个应该先休息一会儿。

所以我们现在电脑里每个运行着的程序都是一个进程,可以打开你的任务管理器(windows)或者活动监视器(mac),看到我们的电脑里其实有好多好多进程喔,什么QQ、微信、音乐播放器、视频播放器啥的。

进程的状态

在操作系统级别上,进程根据它运行的情况,可以分成下边5种状态:

1.新建

刚刚创建的那个时刻,操作系统会为这个进程在内存中创建相应的数据,比如分配这个进程的ID,优先级什么的~这个状态持续的时间比较短。

2.就绪

一旦该进程相关的一些数据创建好了,这个进程就会被放在一个叫就绪队列的队列里,之后操作系统就会从这个队列里挑一个进程放到处理器里执行。

3.运行

这个进程被操作系统分配了时间片,处理器开始执行它。

4.阻塞

在执行进程的过程中,可能遇到某些阻塞的动作,比如I/O操作,处理器如果一直等待该阻塞动作完成的话就太浪费时间了,所以会把等待阻塞动作完成的进程放到一个叫阻塞队列的队列里,之后并不会从这个队列里挑选即将执行的进程,而是直到该阻塞动作完成,才重新把该进程放到就绪队列里等待执行。

5.退出

该进程执行完毕,或者遇到了什么错误,或者操作系统就是想弄死它,它就被杀死了,这个状态里操作系统可能还会记录一下死因啥的,这个过程也很短。

这些状态的具体转换过程看下图:

Java并发编程之背景知识

串行编程和并行编程

到目前为止,我们的编程模式都是串行编程,也就是处理器执行完一条指令再执行另一条。举个例子啊,比如你妈给你布置了两个任务:一是去打瓶酱油,二是去烧一壶水,按照串行编程的方式就是两个任务依次进行,也就是说你先打酱油,然后回来再烧水。这么做没啥问题,但是没有效率啊,所以你也可以先把水烧上,然后去打酱油,回来正好水烧开了~这种多个任务同时进行的编程方式就叫做并行编程。

回到计算机中来,串行编程的方式就是我们把所有要完成的任务放到一个进程中去执行,而并行编程的方式就是我们去开几个进程同时执行(注:这个同时可能是假的,如果只有单个处理器,那就是看上去是同时的)。这种并行编程的优势是显而易见的:

1.充分利用多个处理器

现代计算机的处理器越来越多,不用白不用。如果所有的任务都塞到1个进程中,而计算机实际有100个处理器,那么将会有99%的计算能力将被浪费。

2.防止任务的阻塞

即使是在单个处理器中,为多个任务创建多个进程也是有好处的。先执行的任务可能会需要执行某些I/O操作而造成阻塞,所以就需要等待I/O操作完成才能继续执行。但是如果为每个任务创建一个进程之后,一个任务阻塞掉并不会影响别的任务的正常执行。

3.简化编程的模型

把一个大任务拆分成若干个小任务自然是会事情清晰许多(注:也不是绝对啊),也就是所谓的大事化小,小事化了~所以把各个任务分配到不同进程里去执行在我们编程方面也会容易一些(注:不是绝对啊)。

线程

线程的概念

进程是个好东西,可以给每个任务都分配一个进程以达到并发执行的目的。可是运行了一段时间人们发现还是有一些不好的地方的:

1.不同进程之间的资源不能够共享。

这个对于为了一个大目标细分成的若干小任务很不友好。比方说对于一个网站来说,针对每一个访问网站的连接都去创建一个进程,如果我们想累加一下总的访问连接数就比较麻烦了,因为各个进程不能去修改同一块内存。

2.创建、切换、销毁进程成本太大。

由于我们的主题是java语言里的并发操作,至于操作系统底层对于创建、切换、销毁进程都要做哪些东西不是我们唠叨的范围,但是这些操作的开销真的很大,你知道这一点就好了~

再返回头来看进程的两个特点,一是对资源的所有权,二是可以作为操作系统调度和执行的单位,这两个特点是没有关系的,也就是说独立的,现代的好多操作系统已经把这两个特点给拆开了,可以被调度和执行的单位通常被称作线程或者轻量级进程,而拥有资源所有权的单位通常被称为进程。

小贴士:
由于历史原因,原先的进程既是资源的分配单位,也是调度和执行的单位,所以我们打开一个程序就相当于打开一个进程。
提出线程概念之后,这种打开一个程序就相当于打开一个进程的叫法也被保留了下来。其实现在打开一个程序的意思是打开一个进程并且打开若干个于这个进程相关联的线程
线程的特点.

线程的特点

看一下这个线程的各种特点

1.一个进程至少对应一个线程

操作系统每开始执行一个程序,都会为其分配所需的资源以及创建若干个程序执行流,也就是说会创建一个进程以及若干线程。

2.各个线程可以共享同一个进程中的各种资源

因为线程是从属于某个进程,所以进程中的内存、I/O啥的资源这个线程都可以访问到。接着上边那个例子,我们可以对于每一个连到网站的连接都可以分配一个线程,然后在申请一块儿内存表示连接数,每创建一个线程都把连接数加1,问题就愉快的解决了。

3.创建、切换、销毁线程的成本远低于原先进程的成本

因为只是一个调度和执行的单位,本来就是原先进程概念的一部分,所以创建、切换、销毁线程的成本就小多了。

4.线程通信比进程通信的效率高

原先进程间通信需要配合各种机制,现在线程间由于可以共享内存,所以通信就easy多了。

至于进程间通信需要啥机制我这就不说了,不是我们讨论的范围。
所以线程的提出完美的解决了一开始提出的把不同任务分配给不同进程执行的缺陷,现在我们可以把不同的任务分配给不同的线程去执行,不仅可以方便通信交流,而且创建和使用的成本还低~

线程的状态

由于线程只是单纯的继承了进程中调度和执行的特性,所以原先进程拥有的状态,现在线程一样拥有,也就是:创建就绪执行阻塞退出

总结

由于本篇比较简单,总结就免了。

点赞
收藏
评论区
推荐文章
菜园前端 菜园前端
2年前
什么是JavaScript同步模式?
原文链接:什么是同步模式?大部分单线程任务都会排队执行任务,这就称为同步模式(Synchronous)。同步模式执行中,只涉及到调用栈(Callstack)。现实生活举例就像验核酸一样,我们要排队一个个去验(按顺序排队),当只有一条通道(也就是单线程)时,
桃浪十七丶 桃浪十七丶
4年前
计算机组成原理4.1指令格式
4.1.1指令的基本概念和指令的基本格式操作码:指明CPU进行什么操作。地址码:知指明CPU对谁进行操作。PC:程序计数器,每执行一条指令会1指向下一条指令。指令的概念和基本格式:是指一台计算机执行某种操作的命令,一台计算机的所有指令的集合构成指令集,也叫做指令系统,位于计算机的硬件和OS层面。不同计算机只能执行自己系统的指令,如Intel的x86架构,手
Python的多任务编程
前言Python程序代码都是按自上而下的顺序加载并执行的,但实际需要代码处理的任务并不都是需要按部就班的顺序执行,通常为提高代码执行的效率,需要多个代码执行任务同时执行,也就是多任务编程的需求。基本的计算机模型是由CPU、RAM及各种资源(键盘、硬盘、显卡、网卡等)组成,代码的执行过程,实际就是CPU和相关寄存器及RAM之间的相关处理的过程。在单核CPU场景
Wesley13 Wesley13
3年前
Java虚拟机
  代码编译的结果从本地机器码转换为字节码,是存储格式发展的一小步,却是编程语言发展的一大步。计算机只认识0和1,所以我们的程序需要经过编译器翻译成由0和1组成的二进制格式才能由计算机执行。经过技术的发展,将编写的程序编译成二进制本地机器码已经不是唯一的选择,越来越多的程序语言选择了与操作系统和机器指令无关、平台中立的格式作为程序编译后的存储格式。   
Wesley13 Wesley13
3年前
Java并发编程1
1 为什么要使用多线程使用多线程的原因主要有以下几点:(1)更有效的运用多核心处理器一个线程在一个时刻只能运行在一个处理器核心上,所以单线程程序在同一时刻只能使用一个处理器核心,而多个线程在同一时刻可以使用多个处理器核心,显然能更加有效的运用多核心处理器。(2)更快的响应时间一些较为复杂的代码可以使
Wesley13 Wesley13
3年前
Java 并发编程:进程、线程、并行与并发
一谈到Java并发编程,我们一般就会联想起进程、线程、并行、并发等等概念。那么这些概念都代表什么呢?进程与线程有什么关系?并发与并行又是什么关系呢?进程与线程进程是指程序的一次动态执行过程,通常我们说计算机中正在执行的程序就是进程,每个程序都会对应着一个进程。一个进程包含了从代码加载到执行完成的一个完整过程,它是操作系统资源分配最小单
Wesley13 Wesley13
3年前
Java中多线程并发体系知识点汇总
一、多线程1、操作系统有两个容易混淆的概念,进程和线程。进程:一个计算机程序的运行实例,包含了需要执行的指令;有自己的独立地址空间,包含程序内容和数据;不同进程的地址空间是互相隔离的;进程拥有各种资源和状态信息,包括打开的文件、子进程和信号处理。线程:表示程序的执行流程,是CPU调度执行的基本单位;线程有自己的程序计数器、寄存器、堆栈和帧。同一进
Wesley13 Wesley13
3年前
Java并发(基础知识)—— 创建、运行以及停止一个线程
在计算机世界,当人们谈到并发时,它的意思是一系列的任务在计算机中同时执行。如果计算机有多个处理器或者多核处理器,那么这个同时性是真实发生的;如果计算机只有一个核心处理器那么就只是表面现象。现代所有的操作系统都允许并发地执行任务。你可以在听音乐和浏览网页新闻的同时阅读邮件,我们说这种并发是进程级别的并发。而且在同一进程内,也会同时有多种任务,这些在同一
Wesley13 Wesley13
3年前
Java线程的join操作有什么作用?
计算机为了提升CPU使用效率和交互性而引入了并发机制,任务的执行也抽象成了线程,并发机制让一个CPU能够轮流执行多个线程,从宏观上看多个线程就像是同时执行一样。并发使得线程的执行顺序不容易控制,而实际工程中很多场景都会涉及某个线程需要依赖另外一个或几个线程的执行结果,这就要被依赖的线程需要先执行完,这时就需要join操作。比如下面的场景,假如要计算AB的结
Wesley13 Wesley13
3年前
Java多线程介绍
1\.线程概述1.1线程和进程进程是处于运行过程中的程序,并且具有一定的独立功能并发性:同一个时刻只能有一条指令执行,但多个进程指令被快速轮换执行并行:多条指令在多个处理器上同时执行线程是进程的执行单元1.2多
美凌格栋栋酱 美凌格栋栋酱
5个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(