線程安全和對應的核心概念

線程安全

  • 線程安全的概念:當多個線程訪問某一個類(對象和方法)時,這個類始終都能表現出正確的行為,那么這個類(對象或者方法)就是線程安全的
  • synchronized:可以在任意對象及方法上加鎖,而加鎖的這段代碼稱為‘互斥區’或者“臨界區”
  • 當多個線程訪問myThread的run方法時,以排隊的方式進行處理(這里排隊是按照CPU分配的先后順序而定的),一個線程想要實現synchronized裝飾的方法里的代碼,首先是嘗試獲取鎖,如果可以得到鎖,就可以執行synchronized代碼體的內容;如果拿不到鎖,這個線程就會不斷嘗試去獲取鎖資源,直到拿到為止;而且是多個線程同時去競爭這把鎖(鎖競爭)

Synchronized

  • 同步Synchronized:同步的概念就是共享,如果不是共享的資源就沒有必要進行同步
  • 異步asynchronized:異步的概念就是獨立,相互之間不受到任何制約
  • 同步的目的是為了保證線程的安全,對于線程安全需要保證兩個特性 原子性(同步)和可見性

線程之間通信

  • 線程通信的概念:線程是操作系統中獨立的個體,但是這些個體如果不經過特殊的處理就不能成為一個整體,線程之間的通信就成為整體的必用的方式之一。當線程之間存在通信指揮,系統之間的交互性會更強大,在提高CPU利用率的同時還會使開發人員對于線程任務在處理過程中,進行有效的把控和監督
  • 使用wait/notify方法實現線程之間的通信(這兩個方法都是object的類的方法,即java為所有的對象都提供了這兩個方法)
  • wait和notify必須配合synchronized關鍵字使用
  • wait方法釋放鎖/notify方法不釋放鎖

ThreadLocal概念

  • 線程局部變量,是一種多線程間并發訪問變量的解決方案,與synchronized等加鎖的方式不同,ThreadLocal完全不提供鎖,而使用以空間換時間的手段,為每個線程提供變量的獨立副本,以保障線程的安全
  • 從性能上說,ThreadLocal不具有絕對的優勢,在并發不是很高的情況下,加鎖的性能可能會更好,但是作為一套與鎖完全無關的線程安全解決方案,在高并發量或者競爭激烈的場景,使用ThreadLocal可以在一定程度上減少鎖競爭

Volatile關鍵字核心概念與應用

  • Volatile:主要作用是使變量在多個線程之間可見
  • 阻止指令的重排序,happens-before
  • 一個線程可以執行的操作有使用(use)、賦值(assign)、轉載(load)、存儲(store)、鎖定(lock)、解鎖(unlock)
  • 主內存可以執行的操作有讀(read)、寫(write)、鎖定(lock)、解鎖(unlock),每個操作都是原子的
  • volatile的作用就是強制線程到主內存(共享內存)里去讀取變量,而不是去線程工作內存里去讀取,從而實現了多個線程之間變量的可見,也就是滿足線程安全的可見行

JVM

  • Java Memory Model(Java內存模型),簡稱JVM,用于解決線程對于共享變量的寫入何時對于另一個線程可見
  • 所有變量都存儲在主內存中,每一個線程都有一個私有的本地內存,本地內存是將該線程使用到的變量,從主內存中拷貝到本地
  • 線程對于變量的所有操作(讀取、賦值等)都必須在工作內存中進行,而不能直接讀寫主內存中的變量(volatile變量也不例外)
  • happens-before規則,例如操作A :i=1;操作B:j=i;如果操作Ahappens-before操作B,那么操作B完成之后,j的值一定為1;
  • 因為happens-before關系可以向程序員保證,在操作B執行之前,操作A的執行后的影響【或者說明結果】(修改i的值)對于操作B是可以觀察到的【可見的】

規則

  • 簡而言之,使用happens-before概念來闡述操作之間的內存可見行
  • 程序順序規則:一個線程中的每個操作,happens-before于該線程中的任意后續操作,也就是說,你寫的操作,如果是單線程執行,那么前面的操作就會happens-before于后面的操作
  • 監視器鎖規則:對于一個鎖的解鎖,happens-before于隨后對這個鎖的加鎖
  • Volatile變量規則:對于一個volatile域的寫,happens-before于任意后續對這個volatile域的讀
  • 傳遞性規則:A happens-before B,B happens-before C,則A happens-before C

指令重排序

  • 為了保證程序的最終運行結果需要和在單線程嚴格意義的順序化環境下執行的結果一致,程序指令的執行順序有可能和代碼的順序不一致,這個過程就稱之為指令的重排序
  • 指令的重排序的意義:JVM利用處理器的特性,充分利用多級緩存,多核等進行適當的指令重排序,從而可以充分利用CPU的執行特點,最大程度上發揮機器的性能

Atomic系列類比

  • Atomic系列類封裝了一系列的基礎類型和對象操作,其目的是為了實現原子性
  • AtomicInteger
  • AtomicLong
  • AtomicBoolean
  • AtomicIntegerArray
  • AtomicLongArray
  • AtomicReference
  • 注意:在對Atomic類操作的時候,如果有多個操作執行,那么就是非原子性的,需要加aynchronized進行修飾,保證Atomic類操作的整體原子性

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/447344.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/447344.shtml
英文地址,請注明出處:http://en.pswp.cn/news/447344.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

JDK Unsafe類的使用與CAS原子特性

JDK Unsafe類的使用與CAS原子特性 Java.util.concurrent.atomic包,其中包含了大量使用到Unsafe這個類Java不能直接訪問操作系統的底層,而是通過本地方法來訪問。 Unsafe類提供了硬件級別的原子操作,主要提供了以下功能 內存操作字段的定位和…

寫軟件不是造汽車

寫軟件和做其他事情是不一樣的。當我們制造別的東西的時候——像汽車、玩具、椅子、畫作、甚至包括數字產品如平面圖片和3D模型——我們做出來的成品就是最終的結果。而開發軟件則不是,我們做出來的產品永遠不可能有最終的結果——我們需要向計算機解釋如何根據任意…

線程池核心概述

線程池核心概述 Executors工廠類使用 Executors工廠類底層源碼分析詳解 ThreadPoolExecutor自定義線程池 ThreadPoolExecutor拒絕策略詳解 計算機密集型與IO密集型詳解 如何正確的使用線程池…

網站盈利的10種方式

如果你有自己的網站,而且已經有了不少的流量,你肯定會開始考慮如何通過這個網站來掙一些錢。 在這篇文章中,我會向大家介紹網站最常見的10種盈利方式。 1.按點擊付費廣告 在網站上展示一個按點擊付費的廣告橫幅是最簡單的盈利方式&#xff…

程序員如何創業?

摘要:工作機會減少,讀大學也不是保障。大公司亦不再是構筑職業生涯的安全港灣。透過媒體的鏡頭,創業似乎成了沙漠中唯一的綠洲。然而關于創業,或許少有人給你建議,這里所列出的一些因素都是你可以考慮的。 如果你的年…

Redis數據的類型

Redis一共分為五種基本數據類型:String、Hash、List、Set、Zset. string 內部編碼有三種,raw,embstr,int String 是二進制的。可以存儲序列化對象,圖片,字符串,數值等 set和get方法 &#x…

Redis高級命令與特性以及單點模式的介紹

高級命令 keys * 返回滿足條件的所有key,可以模糊匹配exists 是否存在指定的keypersist 取消過期時間select 選擇數據庫 (0-15,總共16個數據庫)move key index 將當前數據庫的 key 移動到給定的數據庫 db 當中randomkey 隨機返回…

華為副總裁徐家駿離職:年薪千萬工作感悟十二條

從普通的公司職員,到年薪千萬的華為副總裁,再到離開華為轉戰百度,徐家駿的十年從業經歷和經驗可資借鑒,我們從中也可以一窺華為的運作過程。徐家駿是華為數據中心的頭,技術超級牛人,一級部門總監&#xff0…

Redis持久化之RDB和AOF

Redis持久化之RDB和AOF Redis 有兩種持久化方案,RDB (Redis DataBase)和 AOF (Append Only File); RDB 詳解 RDB 是 Redis 默認的持久化方案。在指定的時間間隔內,執行指定次數的寫操作&#…

同為程序員 為什么我的工資最低

我看著工資單上每一個開發團隊成員的薪水,慢慢地我不能保持淡定了。 而當我看到我的工資排名是倒數的時候——靠近最后一名——我不由得倒抽一口冷氣。就像圣誕故事中的那個可愛的小男孩Ralphie ,想買氣槍卻被忽悠會有危險一樣,我也不斷忽悠…

Docker安裝Redis以及配置Redis環境

1,下載Redis鏡像 首先拉取 Redis 鏡像, 這里我選擇的是 redis:alpine 輕量級鏡像版本 docker pull redis:alpine 下載完成后,通過 docker images 查看我們已經下載的鏡像,看看是否已經下載到本地 2,運行 Redis 容器 docker run …

.NET程序性能的基本要領

摘要:本文分享了性能優化的一些建議和思考,比如不要過早優化、好工具很重要、性能的關鍵,在于內存分配等。開發者不要盲目的沒有根據的優化,首先定位和查找到造成產生性能問題的原因點最重要。 【編者按】Bill Chiles&#xff08…

redis.conf配置文件詳解

基本配置 daemonize no #是否以后臺進程啟動databases 16 #創建database的數量(默認選中的是database 0)save 900 1 #刷新快照到硬盤中,必須滿足兩者要求才會觸發,即900秒之后至少1個關鍵字發生變化save 300 10 #必須是300秒之后至少10個關鍵字發生變…

什么原因成就了一位優秀的程序員?

這些年我曾和很多程序員一起工作,他們之中的一些人非常厲害,而另一些人顯得平庸。不久前因為和一些技術非常熟練的程序員工作感覺很愉快,我花了一些時間在考慮我佩服他們什么呢?什么原因讓優秀的程序員那么優秀,糟糕的…

Redis的哨兵模式Sentinel

sentinel功能 redis的sentinel系統用于管理多個redis服務器,該系統主要執行三個任務:監控、提醒、自動故障轉移。 1、監控(Monitoring): Redis Sentinel實時監控主服務器和從服務器運行狀態,并且實現自動…

csdn 到底怎么了?不準轉載?

我轉載了20多文章,很多人閱讀過,但是今天看到閱讀量是0, csdn 到底怎么了? 對用戶這樣?請大家看看是不是這樣?

python3之后版本讀取網頁的內容

import urllib.request url "http://helloworldbook2.com/data/message.txt" #直接通過url來獲取網頁數據 print(第一種) response urllib.request.urlopen(url) code response.getcode() html response.read() mystr html.decode("utf8") response.c…

三十功名塵與土——資深程序員生涯自白

摘要:作者Codist(網名)在程序員崗位上工作了三十多年,在這期間他悟出了一些真理,比如,成功來自對失敗的總結學習;條條大路通羅馬,羅馬并不在乎你用什么方式到達。你在生活中積累了哪…

linux/unix核心設計思想

1) 程序應該小而專一,程序應該盡量的小,且只專注于一件事上,不要開發那些看起來有用但是90%的情況都用不到的特性; 2) 程序不只要考慮性能, 程序的可移植性更重要,shell和perl&…

操作系統環境變量

在 Java中,許多類都是 Iterable ,主要包括所有的 Collection 類(但不包括各種 Maps )。 例如,下面的代碼可以顯示所有的操作系統環境變量: // collections/EnvironmentVariables.java // {VisuallyInspect…