多线程入门
1. 理解线程与进程
由于并发肯定涉及到多线程,因此在进入并发编程主题之前,我们先来了解一下进程和线程的由来,这对后面对并发编程的理解将会有很大的帮助。
进程和线程的对比这一知识点由于过于基础,正因为过于基础,所以我们更应该透彻它!我们必须掌握什么是线程和进程,掌握线程与进程的关系、区别及优缺点 !
1.1、何为进程?
首先我们来看一下进程的概念:
进程:是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程;进程也是程序的一次执行过程,是系统运行程序的基本单位;系统运行一个程序即是一个进程从创建、运行到消亡的过程。
看完之后,是不是感觉很抽象?很懵bi?懵bi就对了,说明你和我智商一样高…开个玩笑
不妨先憋弃上面的概念,放松一下大脑,双击打开LOL,秒选德马打野,输了直接退出游戏并且保持微笑,然后正襟危坐心平气和的看宜春写的博客…
这个时候的你不仅仅是愉快的撸了一把游戏,而且还亲自体验撸了一把进程…其实在你双击打开LOL的时候就已经创建了进程,此话怎讲?众所周知,我们的电脑安装的软件比如:LOL、微信、谷歌等等都是存储在我们的硬盘上的,硬盘上的数据可以说是永久存储(ORM),当我们双击LOL的时候,LOL程序执行就进入了内存中,所有的程序必须进入内存中才能执行,内存属于临时存储(RAM),而进入内存的程序都可以叫做是进程,把LOL程序退出的时候,LOL程序就会退出内存,进程也就随之销毁了!因此说各位撸了一把进程也不为过吧。
啥?字太多了,看的不够明了,不如看图得劲…额。。。
上面主要是通过抽象的描述了进程,其实进程是可以很直观的看的到的,我们可以再电脑底部任务栏,右键----->打开任务管理器,可以查看当前任务的进程:
其实,关于线程博主我完全可以一两句话概括,但是这样并不负责,毕竟这篇文章标题就是要让你彻底入门java多线程。如果连进程都理解不好谈何彻底理解多线程?
1.2、何为线程?
同样的,我们先来看线程的概念
线程是进程中的一个执行单位,负责当前进程中程序的执行。一个进程中至少有一个线程,也就是说一个进程可以有多个线程的,而多个线程的进程运用程序就叫做多线程程序
线程的概念稍微好理解很多,但是想更深层次的去理解光靠上面一段文字的概述是完全不够的!
这不打LOL的过程中,属实卡的一批,果然花高价998买的6手戴尔笔记本打LOL属实像极了爱情。这个时候不得不双击打开电脑安全管家进行杀毒,果然2500天没有进行过病毒查杀,我天。。。其实我相信很多人都用过电脑管家或者手机管家之类的安全软件,我们都很清楚我们开启病毒查杀之后一般要几分钟扫描查杀,这个时候我们是可以让它后台进行的,我们不会等而是开启另一个垃圾清理的功能,这个时候我们也不会等而是再去启动电脑加速功能。等到 这些操作都完成之后果断退出电脑管家,继续LOL,果然高价998买的6手戴尔笔记本再怎么杀毒打LOL还是照样的卡…
其实清楚线程必然涉及到CPU的相关概念了,将上面文字所描述的用图片概括,大致为:
1.3、何为多线程?
从上一节中,我们也提到过多线程,所以理解起来应该不难。
多线程就是多个线程同时运行 或 交替运行。
单核CPU:交替运行。
多核CPU:同时运行。
其实,多线程程序并不能提高程序的运行速度,但能够提高程序运行效率,让CPU的使用率更高。
1.4、何为线程调度优先级?
说起线程调度优先级这个概念,就让我想到现在我们大部分人投简历一样。如果你的学历或者工作经验越高,那么你的优先级就越高,面试官很大几率就会让你去面试但也不是一定只是几率特别大,如果线程的优先级相同,那么会随机选择一个(线程随机性)!在我们每个人的电脑中线程是可以设置线程的优先级的,但是生活中没有优先级(学历、工作经验)的孩子就只能靠自己的能力了妈耶,太真实了…
线程优先级具有继承特性比如A线程启动B线程,则B线程的优先级和A是一样的。
线程优先级具有随机性也就是说线程优先级高的不一定每一次都先执行完,只是被执行的可能性更大。
在今后的多线程学习旅游中我们会使用到getPriority()
方法获取线程的优先级。
1.5、为什么提倡使用多线程而不是多进程?
线程与进程相似,但线程是一个比进程更小的执行单位,是程序执行的最小单位。一个进程在其执行的过程中可以产生多个线程。与进程不同的是同类的多个线程共享同一块内存空间和一组系统资源,所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。同时线程是程序执行的最小单位。使用多线程而不是用多进程去进行并发程序的设计,是因为线程间的切换和调度的成本远远小于进程。
而使用多线程,多线程会将程序运行方式从串行运行变为并发运行,效率会有很大提高。
2、理解并行和并发
在博主认为并发和并行是两个非常容易被混淆的概念。为了防止绕晕大家,所以我选择长话短说!
- 并发:一个
时间段
内同时发生(并不是同时发生)。 - 并行:同一
时刻
发生(真正的同时发生)。
它们都可以表示两个或者多个任务一起执行,但是偏重点有些不同。
于此同时,我们不妨回顾一下上面所提到过的CPU,并再次理解并发与并行的区别,从而温故知新 我TM简直是个天才!
单核CPU:交替运行【并发】
多核CPU:同时运行【并行】
并发给人的感觉是同时运行,那是因为分时交替运行的时间是非常短的!
3、同步
在并发中,我们可以将同步定义为一种协调两个或者更多任务以获得预期结果的机制。同步方式有两种
- 控制同步:例如,当一个任务的开始依赖于另一个任务的结束时,第二个任务不能再第一个任务完成之前开始。
- 数据访问同步:当两个或者更多任务访问共享变量时,在任意时间里,只有一个任务可以访问该变量。
与同步密切相关的一个概念是临界段。临界段是一段代码,由于它可以访问共享资源,因此在任何给定时间内,只能够被一个任务执行。互斥是用来保证这一要求的机制,而且可以采用不同的方式来实现。请记住,同步可以帮助你在完成并发任务的同时避免一些错误(本章稍后将详述),但是它也为你的算法引入了一些开销。你必须非常仔细地计算任务的数量,这些任务可以独立执行,而无须并行算法中的互通信。这就涉及并发算法的粒度。
- 粗粒度:低互通信的大型任务,同步方面的开销就会较低。然而,也许你不会用到系统所有的核心。
- 细粒度:高互通信的小型任务,同步方面的开销就会很大,而且该算法的的吞吐量不是很好。
并发系统中有不同的同步机制。从理论角度来看,最流行的机制如下。
信号量(semaphore):一种用于控制对一个或多个单位资源进行访问的机制。它有一个用于存放可用资源数量的变量,并且可以采用两种原子操作来管理该变量的值。互斥(mutex,mutualexclusion 的简写形式)是一种特殊类型的信号量,它只能取两个值(即资源空闲和资源忙),而且只有将互斥设置为忙的那个进程才可以释放它。互斥可以通过保护临界段来帮助你避免出现竞争条件。
监视器:一种在共享资源之上实现互斥的机制。它有一个互斥、一个条件变量、两种操作(等待条件和通报条件)。一旦你通报了该条件,在等待它的任务中只有一个会继续执行。
4、不可变对象
不可变对象是一种非常特殊的对象。在其初始化后,不能修改其可视状态(其属性值)。如果想修改一个不可变对象,那么你就必须创建一个新的对象。不可变对象的主要优点在于它是线程安全的。你可以在并发应用程序中使用它而不会出现任何问题。
不可变对象的一个例子就是Java 中的String 类。当你给一个String 对象赋新值时,会创建一个新的String 对象。
5、原子操作和原子变量
与应用程序的其他任务相比,原子操作是一种发生在瞬间的操作。
在并发应用程序中,可以通过一个临界段来实现原子操作,以便对整个操作采用同步机制。
原子变量是一种通过原子操作来设置和获取其值的变量。可以使用某种同步机制来实现一个原子变量,或者也可以使用CAS 以无锁方式来实现一个原子变量,而这种方式并不需要任何同步机制。