4

线程安全,这词你懂了吗? - god23bin

 2 years ago
source link: https://www.cnblogs.com/god23bin/p/what-is-thread-safe.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

还记得你第一次遇到「线程安全」这个词的时候吗?

我第一次遇到线程安全这个词是在学习多线程并发操作的时候,看到人家文章里出现这个词,还有说各种线程安全的类,但是一开始并不理解线程安全是什么意思,也没去深究线程怎样是安全的?怎样是不安全的?只是脑子里接收了这么一个词。

线程安全是多线程编程时的计算机程序代码中的一个概念。在拥有共享数据的多条线程并行执行的程序中,线程安全的代码会通过同步机制保证各个线程都可以正常且正确的执行,不会出现数据污染等意外情况。——《百度百科》

默认已学前置知识

  • 进程:程序的一次执行的过程,是动态的,是系统进行资源分配的基本单位。一个进程里可以有多个线程。
  • 线程:是一个系统进行调度的基本单位,是能独立运行的。

下面开始回炉重造!打好基础!

线程安不安全是怎样定义的?

先给出个问题,为什么有线程安全这个词?这个词是怎么来的?可能这里会有点懵,不过没事,我来回答。

在多线程的情况下,我们会遇到这样一个问题,这里举例 A、B、C 三个线程,它们共同操作同一个资源(呐,这里同一个资源指的是,变量,方法这些,更准确的话,应该说是内存,毕竟值都是存储内存中的)。记住,前提是多线程,毕竟如果你单线程,就不可能不安全了,单线程直接安安全全!

A、B、C并发执行

这三个线程同时操作,就可能出现这样的问题,比如举个具体的例子,经典例子,买票(老演员了)!啥票都行。

三个线程代表三个人,票的剩余量对于这三个线程来说就是共享资源。

设票的剩余量为10,记 ticketSurplus = 10。三人购票,那么肯定需要对这个剩余量进行减一操作的。

public void buy() {
    ticketSurplus = ticketSurplus - 1;
    System.out.println(ticketSurplus);
}

那么现在同时执行,就很大可能会出现这样的情况,如图所示(假设这三个线程执行顺序是A、B、C,实际上顺序是不确定的):

执行过程出现的问题

从上面可以看出,输出结果为:9,9,8,而从上帝视角来看,显然是错误的,因为两个人买了票,不能只减一张票的值,正确的结果应该为9,8,7

所以,在多线程并发的情况下,这就是所谓的「不安全」,即不能正确执行,结果出现了混乱(数据污染)。

线程安全?

所谓线程安全,就是指当并发情况下,也就是有多个线程操作同一个资源(具体的话,这里同一个资源可以看成上面例子中的 ticketSurplus,当然这个同一资源也不一定只的是一个变量,也可以是某一个方法),能不能保证这个资源的一致性,如果任何时候都能够保证这种正确的操作结果,那么就可以说是线程安全的。

如何保证线程安全?

在学习操作系统的时候,我们学习了进程管理的内容,其中就有个「进程同步」的概念,所谓进程同步,说简单点就是进程之间具有前后的执行关系。在并发的情况下,不同进程有不同制约关系,比如某些情况下我们是需要 A 进程先执行,然后 B 进程再执行的,但是操作系统具有「异步性」,在并发的情况下,可能出现 B 先执行,A 后执行了,这显然不是我们想要的,所以如果不制约,不控制进程的同步,就会出现上面说的情况。

当然,除了「同步」这个词,还有一个词——「互斥」,互斥也是用于控制进程之间关系的。

同步:完成某种任务,需要进程之间的执行顺序有先后顺序,相互协调工作。

互斥:一个进程进入临界区访问临界资源,那么剩下的进程就需要进行等待,只有当它退出临界区,才允许下一个进程访问。

在 Java 中,我们可以通过 synchronized 关键字来保证临界区的同步互斥,当然还有其他的锁也可以实现同步互斥,进而保证多线程运行的安全。

总的来说,在多线程的情况下,通过加锁的方式保证线程安全。

最后的最后

由本人水平所限,难免有错误以及不足之处, 屏幕前的靓仔靓女们 如有发现,恳请指出!

最后,谢谢你看到这里,谢谢你认真对待我的努力,希望这篇博客对你有所帮助!

你轻轻地点了个赞,那将在我的心里世界增添一颗明亮而耀眼的星!


Recommend

  • 37

    有问题,上知乎。知乎是中文互联网知名知识分享平台,以「知识连接一切」为愿景,致力于构建一个人人都可以便捷接入的知识分享网络,让人们便捷地与世界分享知识、经验和见解,发现更大的世界。

  • 6
    • www.cnblogs.com 2 years ago
    • Cache

    我操作MySQL的惊险一幕 - god23bin

    我操作MySQL的惊险一幕 ...

  • 7

    项目中有一个查重的需求,就类似论文查重这种的需求,我的组长已经写好了这个 Demo 了,我也挺感兴趣的,所以也看了看是如何实现的,看完后,感慨一声,噢!原来是这样实现的啊!现在呢,就记录下我从中学到的知识! 输入:需要查重的内容,通常是非常长的文...

  • 5

    学过定时任务,但是我忘了,忘得一干二净,害怕,一直听别人说: 你写一个定时任务就好了。 写个定时任务让他去爬取就行了。 我不会,所以现在得补回来了,欠下的终究要还的,/(ㄒoㄒ)/~~

  • 8

    浅入浅出 1.7和1.8的 HashMap HashMap 是我们最最最常用的东西了,它就是我们在大学中学习数据结构的时候,学到的哈希表这种数据结构。面试中,HashMap 的问题也是常客,现在卷到必须答出来了,是必须会的知...

  • 7

    《回炉重造》——Lambda表达式 - god23bin - 博客园 Lambda 表达式(Lambda Expression),相信大家对 Lambda 肯定是很熟悉的,毕竟我们数学上经常用到它,即 λ 。不过,感觉数学中的 Lambda 和编程语言中的 Lambda 表达式没啥...

  • 5

    什么是Servlet? 前置知识: Web 服务器:可以指硬件上的,也可以指软件上的。从硬件的角度来说, Web 服务器指的就是一台存储了网络服务软件的计算机;从软件的角度来说, Web 服务器指的是一种软件,比如 Tom...

  • 7

    在 Web 应用程序中(通俗点,可以理解成一个网站),Session 和 Cookie 是两个非常重要的概念,主要用于实现用户身份认证、数据传递等功能。今天就来讲讲这两个东西。 对于当时刚开始接触到这两个概念的我来说,这两个东西是非常模糊的,当然,这样也和我自己...

  • 13

    在现在的日常开发中,不管前端还是后端,JSON 格式的数据是用得比较多的,甚至可以说无处不在。 接触最多的就是 POST 请求中传递的数据一般以 JSON 的格式放在请求体中,而且服务端各种 API 返回的数据,在响应体中也基本都是...

  • 5

    一般项目中的初始化操作,初次遇见,妙不可言。如果你还有哪些方式可用于初始化操作,欢迎在评论中分享出来~ ApplicationRunner 和 CommandLineRunner Spring Boot 应用...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK