自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

你真的知道什么是線程安全嗎?

安全 應(yīng)用安全
如果面試官問(wèn)你,線程安全的類有哪些,究竟什么是線程安全?你怎么回答呢?我們整天說(shuō)線程安全,但你真的知道什么是線程安全嗎?

 [[340476]]

本文轉(zhuǎn)載自微信公眾號(hào)「老胡愛(ài)分享」,作者 hoohack。轉(zhuǎn)載本文請(qǐng)聯(lián)系老胡愛(ài)分享公眾號(hào)。

如果面試官問(wèn)你,線程安全的類有哪些,究竟什么是線程安全?你怎么回答呢?我們整天說(shuō)線程安全,但你真的知道什么是線程安全嗎?

什么是進(jìn)程

從學(xué)術(shù)上理解,進(jìn)程就是包含上下文切換的程序執(zhí)行時(shí)間總和 = CPU加載上下文+CPU執(zhí)行+CPU保存上下文。

另一個(gè)簡(jiǎn)單的理解,進(jìn)程就是程序的一次執(zhí)行,比如看看一下這個(gè)圖,每一個(gè)運(yùn)行中的程序就是一個(gè)獨(dú)立的進(jìn)程,進(jìn)程是相互獨(dú)立存在的。

什么是線程

線程就是CPU執(zhí)行那一部分的一個(gè)個(gè)小段,線程是CPU的基本調(diào)度單位。

注:平時(shí)大家說(shuō)“因?yàn)镽edis是單線程的,所以它是原子性的”,根本原因是,因?yàn)榫€程是CPU的最小調(diào)度單元,CPU每次只能執(zhí)行成功或者失敗才調(diào)度切換到下一個(gè)線程,所以Redis的操作都是原子的。

進(jìn)程和線程都是一個(gè)時(shí)間段的描述,是CPU工作時(shí)間段的描述,不過(guò)是顆粒大小不同。

堆和棧

進(jìn)程與線程中比較重要的內(nèi)存區(qū)域有堆和棧。

堆是進(jìn)程和線程共有的空間,分全局堆和局部堆。全局堆就是所有沒(méi)有分配的空間,局部堆就是用戶分配的空間。堆在操作系統(tǒng)對(duì)進(jìn)程初始化的時(shí)候分配,運(yùn)行過(guò)程中也可以向系統(tǒng)要額外的堆,但是用完了要還給操作系統(tǒng),要不然就是內(nèi)存泄漏。

在Java中,堆是Java虛擬機(jī)所管理的內(nèi)存中最大的一塊,是所有線程共享的一塊內(nèi)存區(qū)域,在虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建。堆所存在的內(nèi)存區(qū)域的唯一目的就是存放對(duì)象實(shí)例,幾乎所有的對(duì)象實(shí)例以及數(shù)組都在這里分配內(nèi)存。

棧是每個(gè)線程獨(dú)有的,保存其運(yùn)行狀態(tài)和局部自動(dòng)變量的。棧在線程開(kāi)始的時(shí)候初始化,每個(gè)線程的棧互相獨(dú)立,因此,棧是線程安全的。操作系統(tǒng)在切換線程的時(shí)候會(huì)自動(dòng)切換棧。棧空間不需要在高級(jí)語(yǔ)言里面顯式的分配和釋放。

進(jìn)程和線程中的數(shù)據(jù)

程序幾乎都需要與數(shù)據(jù)打交道,讀取數(shù)據(jù)(命令行參數(shù),文件),寫入數(shù)據(jù)(設(shè)置變量,寫入文件)。這些數(shù)據(jù)是保存在進(jìn)程所管理的內(nèi)存里。

為了保證數(shù)據(jù)的安全,比如一個(gè)進(jìn)程中修改的數(shù)據(jù)不會(huì)影響到另一個(gè)進(jìn)程的數(shù)據(jù),每一個(gè)進(jìn)程都會(huì)擁有操作系統(tǒng)分配給自己的內(nèi)存空間,而不能訪問(wèn)其他進(jìn)程的數(shù)據(jù),這一點(diǎn)是由操作系統(tǒng)保證的。

進(jìn)程占有的資源:地址空間,全局變量,打開(kāi)的文件,子進(jìn)程,信號(hào)量,賬戶信息

線程占有的資源:棧,寄存器,狀態(tài),程序計(jì)數(shù)器

進(jìn)程是操作系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)獨(dú)立單位,不會(huì)共享資源,通過(guò)進(jìn)程間通信共享資源,而線程可以共享部分資源,獨(dú)自占有的資源不共享。

線程間共享的數(shù)據(jù)包括:

  • 1、堆
  • 2、進(jìn)程代碼段
  • 3、進(jìn)程的公有數(shù)據(jù)

對(duì)于線程間共享的內(nèi)存區(qū)域,如果進(jìn)程中的A線程操作了數(shù)據(jù),切換到B線程執(zhí)行,修改了同樣的數(shù)據(jù),回到A線程時(shí),數(shù)據(jù)就不是A線程切換時(shí)候的樣子,這樣一來(lái),數(shù)據(jù)就被污染了,我們就說(shuō)這塊數(shù)據(jù)在多線程環(huán)境下是不安全的,即線程不安全的。

這就是線程安全這個(gè)概念產(chǎn)生的背景,筆者認(rèn)為,談?wù)摼€程安全性,一定需要先介紹操作系統(tǒng)中進(jìn)程與線程操作內(nèi)存的過(guò)程,否則,說(shuō)一個(gè)對(duì)象是安全的還是不安全的就顯得有點(diǎn)突兀,而且相對(duì)于什么是安全的也不知道。

線程安全性

《Java并發(fā)編程實(shí)戰(zhàn)》給出的定義如下:

一個(gè)對(duì)象是否需要是線程安全的,取決于它是否被多個(gè)線程訪問(wèn)。這只和對(duì)象在程序中是以何種方式被使用的有關(guān),和對(duì)象本身具體是做什么的無(wú)關(guān)。

當(dāng)多個(gè)線程訪問(wèn)某個(gè)類時(shí),這個(gè)類始終都能表現(xiàn)出正確的行為,那么就稱這個(gè)類是線程安全的。

線程安全的程序不一定是由線程安全的類組成,完全由線程安全類組成的程序也不一定是線程安全的。還需要一定的組合技巧才能保證線程安全。

要編寫線程安全的代碼,其核心在于要對(duì)對(duì)象狀態(tài)訪問(wèn)操作進(jìn)行管理,特別是對(duì)共享的(Shared)和可變的(Mutable)狀態(tài)的訪問(wèn),即數(shù)據(jù)的訪問(wèn),而數(shù)據(jù)是存儲(chǔ)在內(nèi)存中,也就是說(shuō),線程安全的本質(zhì)不是代碼在線程中的安全,而是線程中內(nèi)存的安全。

至此,線程安全的概念介紹完畢,最后的最后,你知道有哪些方法可以保證線程安全嗎?

總結(jié)

分享一個(gè)學(xué)習(xí)方法,帶著問(wèn)題去看書。有時(shí)候看一本書,從頭到尾看完確實(shí)非??菰餆o(wú)味,且很容易就放棄了,最近想到一個(gè)方法就是帶著問(wèn)題去看,比如《Java并發(fā)編程實(shí)戰(zhàn)》,據(jù)說(shuō)是Java并發(fā)編程的神書,但是很枯燥,而且中文版也難懂,看了好多次之后沒(méi)能進(jìn)入狀態(tài),后來(lái)就想著,能不能去網(wǎng)上看看一些面試題,看看這本書究竟能給我解答什么疑惑,懷著這樣的心情,就把前三章看完了。

帶著問(wèn)題去看,目的性較強(qiáng),更容易去理解,再通過(guò)自己的語(yǔ)言描述出來(lái),印象就更深刻了。

 

責(zé)任編輯:武曉燕 來(lái)源: 老胡愛(ài)分享
相關(guān)推薦

2022-09-28 18:16:34

JavaJDK

2016-09-29 15:43:33

2023-07-11 00:12:05

2015-10-23 09:34:16

2023-12-20 08:23:53

NIO組件非阻塞

2015-12-01 13:33:51

UnikernelLinux運(yùn)維

2021-11-12 05:59:23

容災(zāi)備份5G

2024-10-10 16:53:53

守護(hù)線程編程

2017-06-23 15:45:09

AndroidThread

2022-11-28 00:04:17

2024-01-15 12:16:37

2022-09-22 14:55:31

前端JavaScripthis

2022-09-26 13:10:17

JavaScriptthis

2021-02-19 07:59:21

數(shù)據(jù)埋點(diǎn)數(shù)據(jù)分析大數(shù)據(jù)

2025-01-16 16:41:00

ObjectConditionJDK

2023-06-26 08:20:02

openapi格式注解

2017-11-02 16:03:12

2024-07-30 08:22:47

API前端網(wǎng)關(guān)

2024-11-08 09:48:38

異步編程I/O密集

2019-03-14 12:39:55

安全云計(jì)算深信服
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)