01 java并发编程要解决的三大问题

  1. 1 并发简史
  2. 2 java中的并发编程

1 并发简史

在计算机发明早期,一台计算机在同一时间只能运行一个程序。如果将人比作一台计算机的话,就是一个人在同一时间内只能做一件事情不能三心二意。就拿博主我给老婆做最爱吃的皮蛋瘦肉粥来说,要经历洗米、把米放锅中煮、切肉和皮蛋、找准火候放入肉和皮蛋、电饭煲闷煮、电饭煲提示灯亮后给老婆大人盛饭,我们要按照顺序执行每一步,在得到结果后再执行下一步,最后得到最终的结果。同样对于早期的计算机来说,交给它一个任务如计算1+2的结果并打印,其要先分别拿到1和2放到寄存器中、然后执行加法运算得出结果3、然后把3回写到内存中、最后把结果通过打印机输出到纸上。大略一看,这个观点似乎没什么问题,但是效率上其实还可以提升下,不管是在人做饭还是计算机执行算数任务这件事上。

不管是人还是机器,都需要提高自身资源的使用效率。人在做饭时最主要使用的是眼睛、双手、和大脑,我们另外一个主要器官耳朵在做饭过程中的使用率并不是太高,这样我们就可以变做饭边听早间新闻提高我们自身器官的使用率,那么效率自然也就提升了。对于计算机来说道理也是相同,在计算机执行计算任务时主要使用的是CPU,在计算机回写计算结果时使用的主要是I/O设备,如果我们能让计算机在执行1+2任务的计算部分时,能让闲置的I/O设备忙起来搞其它任务的输入或者输出部分的工作;亦或在计算机通过I/O设备将1+2的计算结果打印到纸上时,让闲置的CPU来执行其它任务的计算部分。那么假设本来需要两个小时完成的类似1+2这种计算结果并打印的大量任务,现在提升效率后大体只需要一个小时就能完成了。

人们为了提升计算机各种设备的使用效率,引入了操作系统来统一管理计算机中的各种设备。所有的任务只需要和操作系统打交道,由操作系统统一调度计算机中的各种设备,尽最大可能保证各种设备在同一时间没有被闲置。操作系统除了保证各种设备没有被闲置外,还要保证各种任务在使用计算机设备时尽可能的公平,当我们用计算机的CPU解码mp3文件听歌时,不能因要执行1+2的计算任务把CPU抢占过去后不能听歌曲了,操作系统会把任务对CPU的使用时间切成无数小的几毫秒的时间片段,每个任务交替的获取使用CPU的时间片段来保证各个任务在执行顺序上的公平。不同任务对CPU按照时间片来交替使用,这个叫做并发。

2 java中的并发编程

上节我们知道计算系统分配CPU时间片的最小单位是一个个具体的任务,操作系统提供线程的概念给各种各样的程序,程序把一个大任务按照不同的性质分隔成小任务,每个小任务被封装在一个线程中交给操作系统来调度执行。同一个程序中的线程有如下特点:

  • 资源共享,操作系统分配给程序的各种资源对于线程来说都是共享的,如内存,CPU等。

  • 线程之间是交替执行的,一个程序中的线程一般是不会少于机器的CPU数量的,这势必导致同一时间点,并不是所有的程序线程都在运行。

java中的并发编程问题也就是对线程和线程能访问到的资源的管理问题,即怎样管理线程和资源才能让程序的执行效率更高同时不出差错。具体来说就是解决以下三大问题:

  1. 正确性问题。由于线程可以共享程序中的各种资源,这有可能导致多个线程对同一个资源的竞争使用,使原来单线程顺序执行时正确的程序,在多线程下出现问题。

  2. 可行性问题。由于对锁的管理不当,导致发生死锁问题,而程序中的死锁可能导致程序“僵死”,没办法完成指定的任务。当然多线程的可行性问题不全是死锁导致的,还有线程饥饿,活锁等多种可能。

  3. 高效性问题。引入多线程后原本一个线程用来执行任务现在交给多个线程一起执行了,效率一定会更高吗?其实并不是绝对的,为了保证多线程程序的正确性和可行性,势必会引入管理成本,同时线程在切换时间片的时候也会有成本。如果平衡不好这些成本,多线程的引入可能带来的是效率的倒退。

这里栗子给大家举个例子,多线程程序就好比是一个交通系统,一辆汽车就好比是一个线程,其中的道路就好比是线程运行时所需要的各种公共资源。如果交通管理系统没能正确的调度其上运行的车辆,让南北行驶的汽车(线程1)和东西行驶的汽车(线程2)同时经过(操作)了交通路口(公共资源)而出了车祸(出现脏数据),这就是没解决好正确性问题;如果因为交通系统调度不合理导致很多车辆相互“顶牛”(A线程拿着B线程要用的资源1,B线程拿着A线程要用的资源2,大家都不释放),互不让路,这就会出现可行性问题;一个调度良好的交通系统能让车辆的吞吐率大幅度提升,这就是高效性问题。

这三大问题正确性是基本,不管是不是并发编程,首先你要保证执行结果是正确的;其次是可行性,程序如果引入了java并发编程先不说效率能提升多少,最起码程序能够顺利执行完成;最后是高效性问题,在满足正确性和可行性时,我们希望我们的程序能在java并发的加持下,相较于单线程顺序执行的程序能更快地完成任务。栗子本系列文章就是围绕这三大问题展开的,而深入了解这三大问题,相信大家会对java多线程有一个更加深刻的认识。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 lmyuanwork@163.com

文章标题:01 java并发编程要解决的三大问题

本文作者:aworker

发布时间:2020-05-17, 13:28:13

最后更新:2020-05-22, 23:10:34

原始链接:http://aworker.cn/2020/05/17/java/concurrency/post1/three_problem_in_java_conccurency/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏