淘宝快3怎么追号|淘宝快3技巧稳赚
天道不一定酬所有勤
但是,天道只酬勤

深入理解Java并发编程(一):到底什么是线程安全

开发十年,就只剩下这套架构体系了!!

本文是搞点事情!死磕Java并发编程。中的一篇试读文章,更多文章,请参见:深入理解Java并发编程

什么是线程安全

线程安全,维基百科中的解释是:

线程安全是编程中的术语,指某个函数、函数库在并发环境中被调用?#20445;?#33021;够正确地处理多个线程之间的共享变量,使程序功能正确完成。

我们把这个定义拆解一下,我们需要弄清楚这么几点: 1、并发 2、多线程 3、共享变量

并发

提到线程安全,必须要提及的一个词那就是并发,如果没有并发的话,那么也就不存在线程安全问题了。

什么是并发

并发(Concurrent),在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行。

那么,操作系统视如?#38382;?#29616;这种并发的呢?

现在我们用到操作系统,无论是Windows、Linux还是MacOS等其实都是多用户多任务分时操作系统。使用这些操作系统的用户是可以“同时”干多件事的。

但是实际上,对于单CPU的计算机来说,在CPU中,同一时间是只能干一件事儿的。为了看起来像是“同时干多件事?#20445;?#20998;时操作系统是把CPU的时间划分成长短基本相同的时间区间,即”时间片?#20445;?#36890;过操作系统的管理,把这些时间片?#26469;?#36718;流地分配给各个用户使用。

如果某个作业在时间片结束之前,整个任务还没有完成,那么该作业就被暂停下来,放弃CPU,等待下一轮循环再继续做.此时CPU又分配给另一个作?#31561;?#20351;用。

由于计算机的处理速度很快,只要时间片的间隔取得适当,那么一个用户作业从用完分配给它的一个时间片到获得下一个CPU时间片,中间有所”停顿?#20445;?#20294;用户察觉不出来,好像整个系统全由它”独占”似的。

所以,在单CPU的计算机中,我们看起来“同时干多件事?#20445;?#20854;实是通过CPU时间片技术,并发完成的。

提到并发,还有另外一个词容易和他混淆,那就是并行。

并发与并行之间的关系

并行(Parallel),当系统有一个以上CPU?#20445;?#24403;一个CPU执行一个进程?#20445;?#21478;一个CPU可以执行另一个进程,两个进程互不抢占CPU?#35797;矗?#21487;以同时进行,这种方式我们称之为并行(Parallel)。

Erlang 之父 Joe Armstrong 用一张比较形象的图解释了并发与并行的区别:

concurrent vs parallel

并发是两个队伍交替使用一台咖啡机。并行是两个队伍同时使用两台咖啡机。

?#25104;?#21040;计算机系统中,上图中的咖啡机就是CPU,两个队伍指的就是两个进程。

多线程

进程和线程

理解了并发和并行之间的关系和区别后,我们再回到前面介绍的多任务分时操作系统,看看CPU是如何进行进程调度的。

为了看起来像是“同时干多件事?#20445;?#20998;时操作系统是把CPU的时间划分成长短基本相同的”时间片?#20445;?#36890;过操作系统的管理,把这些时间片?#26469;?#36718;流地分配给各个用户的各个任务使用。

在多任务处理系统中,CPU需要处理所有程序的操作,当用户来回切换它们?#20445;?#38656;要记录这些程序执行到哪里。在操作系统中,CPU切换到另一个进程需要保存当前进程的状态并?#25351;?#21478;一个进程的状态:当前运行任务转为就绪(或者挂起、?#22659;?#29366;态,另一个被选定的就绪任务成为当前任务。上下文切换就是这样一个过程,他允许CPU记录并?#25351;?#21508;种正在运行程序的状态,使它能够完成切换操作。

在上下文切?#36824;?#31243;中,CPU会停止处理当前运行的程序,并保存当前程序运行的具体位置以便之后继续运行。从这个角度来看,上下文切换有点像我们同时阅读几本书,在来回切换书本的同时我们需要记住每本书当前读到的页码。在程序中,上下文切?#36824;?#31243;中的“页码”信息是保存在进程控制块(PCB)中的。PCB还经常被称作“切换帧?#20445;╯witchframe)。“页码”信息会一直保存到CPU的内存中,直到他们被再次使用。

对于操作系统来说,一个任务就是一个进程(Process),?#28909;?#25171;开一个浏览器就是启动一个浏览器进程,打开一个记事本就启动了一个记事本进程,打开两个记事本就启动了两个记事本进程,打开一个Word就启动了一个Word进程。

而在多个进程之间切换的时候,需要进行上下文切换。但是上下文切换势必会耗费一些?#35797;础?#20110;是人们考虑,能不能在一个进程中增加一些“子任务?#20445;?#36825;样减少上下文切换的成本。?#28909;?#25105;们使用Word的时候,它可以同时进行打字、拼写检查、字数统计等,这些子任务之间共用同一个进程?#35797;矗?#20294;是他们之间的切换不需要进行上下文切换。

在一个进程内部,要同时干多件事,就需要同时运行多个“子任务?#20445;?#25105;们把进程内的这些“子任务”称为线程(Thread)。

随着时间的慢慢发展,人们进一步的切分了进程和线程之间的职责。把进程当做?#35797;?#20998;配的基本单元,把线程当做执行的基本单元,同一个进程的多个线程之间共享?#35797;?/strong>

拿我们比较熟悉的Java语言来说,Java程序是运行在JVM上面的,每一个JVM其实就是一个进程。所有的?#35797;?#20998;配都是基于JVM进程来的。而在这个JVM进程中,又可?#28304;?#24314;出很多线程,多个线程之间共享JVM?#35797;矗?#24182;且多个线程可以并发执行。

共享变量

所谓共享变量,指的是多个线程都可以操作的变量。

前面我们提到过,进程视分配?#35797;?#30340;基本单位,线程是执行的基本单位。所以,多个线程之间是可以共享一部分进程中的数据的。在JVM中,Java堆和方法区的区域是多个线程共享的数据区域。也就是说,多个线程可以操作保存在堆或者方法区中的同一个数据。那么,换句话说,保存在堆和方法区中的变量就是Java中的共享变量。

那么,Java中哪些变量是存放在堆中,哪些变量是存放在方法区中,又有哪些变量是存放在栈中的呢?

类变量、成员变量和局部变量

Java中共有三种变量,分别是类变量、成员变量和局部变量。他们分别存放在JVM的方法区、堆内存和栈内存中。

/**
 * @author Hollis
 */
public class Variables {

    /**
     * 类变量
     */
    private static int a;

    /**
     * 成员变量
     */
    private int b;

    /**
     * 局部变量
     * @param c
     */
    public void test(int c){
        int d;
    }
}

上面定义的三个变量中,变量a就是类变量,变量b就是成员变量,而变量c和d是局部变量。

所以,变量a和b是共享变量,变量c和d是非共享变量。所以如果遇到多线程场景,对于变量a和b的操作是需要考虑线程安全的,而对于线程c和d的操作是不需要考虑线程安全的。

小结

在了解了一些基础知识以后,我们再来回过头看看线程安全的定义:

线程安全是编程中的术语,指某个函数、函数库在并发环境中被调用?#20445;?#33021;够正确地处理多个线程之间的共享变量,使程序功能正确完成。

现在我们知道了什么是并发环境,什么是多个线程以及什么是共享变量。那么只要我们在编写多线程的代码的时候注意一下,保证程序功能可以正确的执行就行了。

那么问题来了,定义中说线程安全能够正确地处理多个线程之间的共享变量,使程序功能正确完成

多线程场景中存在哪些问题会导致无法正确的处理共享变量? 多线程场景中存在哪些问题会导致程序无法正确完成? 如何解决多线程场景中影响『正确』的这些问题? 解决这些问题的各个手段的实现原理又是什么?

以上问题会在后续文章中介绍。

(全文完) ?#38431;?#20851;注『Java之道』微信公众号
赞(42)
如未加特殊说明,此网站文章均为原创,转载必须注明出处。HollisChuang's Blog » 深入理解Java并发编程(一):到底什么是线程安全
分享到: 更多 (0)

评论 1

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
  1. #1

    你好,探讨一下,在小节“类变量、成员变量和局部变量”中,写道“变量a和b是共享变量,变量c和d是非共享变量”。
    但如果c和d是非基本类?#20572;?#23545;象),且声明为final,即可在此方法域内声明的新线程进行共享,此时c和d也是线程共享的变量了。所以我理解局部变量,不一定是线程安全的吧?

    hh6plus4个月前 (02-23)回复

HollisChuang's Blog

联系我关于我
淘宝快3怎么追号 头条号推荐量一般多少 老重庆实时走势图360 老时时综合走势图 腾讯扎金花三张牌 得意黑龙江麻将下载苹果 彩客站快三跟计划是真的吗 河北福彩好运彩3开奖结果 香港特马免费资料大全 今天天津快三开奖结果 钱柜老虎机手机版登录pt