java并發編程實戰-第三章-對象的共享

3.1可見性

  • 首先我們需要知道的是,java的線程都有自己獨立的緩存,線程之間進行共享變量的交互是通過自身和緩存和主存的交互實現的。
  • 如果線程的每次更改緩存都刷入主存,主存每次被一個線程的緩存修改,都通知所有的線程刷新自身的緩存的話,那樣就太不經濟了。
  • 由于1和2,就會產生一個現象:當線程1修改了一個共享變量之后,線程2獲取的共享變量還是更改前的值。即線程1更改共享變量并沒有刷入主存,或者線程2并沒有去主存中獲取到新的共享變量,或以上兩者皆有
  • 為了解決內存可見性我們可以使用volatile關鍵字和同步這兩種方式
  • 變量的讀取,指令重排序

失效數據

非原子的64位操作

當讀取一個非volatile類型的long變量時,如果對該變量的讀操作和寫操作在不同的線程中執行,那么很可能讀取到某個值的高32位和另外一個值的低32位

加鎖和可見性

加鎖的含義不僅互斥,還包括內存可見性

volatile變量

  • 用來確保變量的更新操作通知到其他線程
  • 編譯器與運行時都會注意到這個變量時共享的,不會進行重排序
  • volatile不會被緩存在寄存器或者其他處理器不可見的地方,讀取變量時,總能返回最新的寫入值

滿足所有條件,才應該使用volatile

  • 對變量的寫入不依賴變量的當前值,只有單個線程更新變臉的值
  • 該變量不會與其他狀態一起納入不變形條件中
  • 在訪問時不需要加鎖

3.2發布與溢出

一般自定義類需要考慮發布(構造方法), juc的類已經處理過了

發布:是對象能夠在當前作用域之外的代碼中使用

  • 將對象的引用存儲到公共靜態域。
  • 在非私有方法中返回引用。
  • 在發布某對象的時候可能會間接發布本不想發布的對象,如一個private的數組,一旦被發布,其中儲存的對象也會被發布

溢出:不應該發布的被發布了

類對自己的內部狀態進行了同步操作,如果發布出去可能會破壞封裝性,并使程序難以維護不變性條件 一個對象在尚未準備好就將它發布出去——溢出。

  • “內部類發布也會引發溢出”,因為只有當對象通過構造函數返回之后,才處于穩定狀態。這種發布會導致this溢出。
  • “即使在構造函數的最后一行發布也會有該問題”,指令重排序可能會引發一些奇怪的問題。而且該引用已經不是null了,但是內容還沒有初始化完畢也有可能。
  • “不要讓this在構造期溢出!”

常見錯誤

  • 1.在構造函數中創建并啟動線程 這個時候線程已經獲得了this的引用(即使是隱式的,因為該Runnable或者Thread是所屬對象的內部類),this引用幾乎總是被新線程所共享。 所以在構造函數中創建線程沒有錯誤,但是不要在構造函數中啟動它。
  • 2.注冊一個內部類,使用this方法 可以使用靜態工廠和私有構造函數來解決這個問題。

3.3線程封閉

數據僅在單線程中被訪問,即數據不共享。 幾種方式:

特定的方法

例如在一個線程中進行 讀取修改寫入,其他線程中進行讀取

棧封閉

引用在局部變量中 注意不要讓當前線程中的對象從所在線程溢出!

java的ThreadLocal

使用ThreadLocal可以做到線程隔離,每個線程都有自己單獨的一個區域保存變量。

3.4不變性對象

  • 不可變對象滿足下列條件:
    1. 所有域是final的,域內部的域也是final的
    2. 所有域不可改變
    3. this沒有在構造的時候逸出

final域

使用volatile類型來發布不可變對象

3.5安全發布

不正確的發布:正確的對象被破壞

導致其他縣城看到尚未創建完的對象

不可變對象與初始化安全

安全發布的常用模式

  1. 在靜態初始化對象引用,因為JVM的類加載過程中是同步的
  2. 對對象引用使用volatile或AtomicReference
  3. 將對象引用放入final域中
  4. 對對象引用加鎖

案例:

  • 將一個鍵值對放入HashTable,syhronizedMap或者ConcurrentMap中
  • 靜態構造的對象 public static Holder holder= new Holder(42)

事實不可變對象

程序不會去修改,例如Date雖然是可變的,但是放入了同步的HashMap中,且不會修改,那么就認為是不可變的對象

可變對象

  • 不僅要保證發布時的狀態可見性
  • 每次訪問時同樣需要使用同步來確保后需修改操作的可見性

小結

  • 不可變對象可以通過任意機制來發布()
  • 事實不可變對象必須通過安全方式來發布
  • 可變對象必須通過安全方式來發布,并且是線程安全的或者由某個所保護起來

安全的共享對象

在發布一個對象的時候需要明確指出該對象的多線程共享規則:

  1. 是線程封閉?:只能由一個線程擁有
  2. 是只讀共享?:只能并發讀
  3. 是線程安全共享?:類內部實現了同步,可以隨意使用
  4. 是保護對象?:類內部沒有實現同步,需要使用者在外部同步 原文地址: www.victor123.cn/2018/04/15/…

轉載于:https://juejin.im/post/5ad2a0a45188257ddb100f27

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

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

相關文章

GitHub(從安裝到使用)

一、安裝Git for Windows(又名msysgit) 下載地址: https://git-for-windows.github.io/ 在官方下載完后,安裝到Windows Explorer integration的時候,將選項中將“Git Bash here”和“Git GUI here”打對勾。 然后就一直next直到Fi…

Spring事務配置的五種方式和spring里面事務的傳播屬性和事務隔離級別、不可重復讀與幻讀的區別

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。 spring事務配置的五種方式 前段時間對Spring的事務配置做了比較深入的研究,在此之間對Spring的事務配置雖說也配置過&#x…

Google編程之夏入圍項目公布

Google編程之夏(Google Summer of Code),是由Google公司所主辦的年度程式設計比賽,第一屆從2005年開始。“Summer of Code”之名取自1967年的“夏日之愛”(Summer of Love)風潮。比賽的主要目的是鼓勵學生參…

普通索引 唯一索引 主鍵索引 候選索引

普通索引 最基本的索引類型&#xff0c;沒有唯一性之類的限制。普通索引可以通過以下幾種方式創建&#xff1a; 創建索引&#xff0c;例如CREATE INDEX <索引的名字> ON tablename (列的列表)&#xff1b; 修改表&#xff0c;例如ALTER TABLE tablename ADD INDEX [索引…

Android 基于注解IOC組件化/模塊化的架構實踐

當前參與的項目歷史也很久遠&#xff0c;第一行代碼據說是寫于2014年的某一天&#xff0c;那時Android用的ide還是Eclipse、那時Android還沒有很好的架構指導&#xff08;mvp、mvvm&#xff09;、那時Android最新的版本是5.0、那時Android的Material Design還沒流行……背景隨著…

網絡爬蟲--14.【糗事百科實戰】

文章目錄一. 要求二. 參考代碼一. 要求 爬取糗事百科段子&#xff0c;假設頁面的URL是 http://www.qiushibaike.com/8hr/page/1 使用requests獲取頁面信息&#xff0c;用XPath / re 做數據提取 獲取每個帖子里的用戶頭像鏈接、用戶姓名、段子內容、點贊次數和評論次數 保存到…

bzoj 5369: [Pkusc2018]最大前綴和

Description 小C是一個算法競賽愛好者&#xff0c;有一天小C遇到了一個非常難的問題&#xff1a;求一個序列的最大子段和。 但是小C并不會做這個題&#xff0c;于是小C決定把序列隨機打亂&#xff0c;然后取序列的最大前綴和作為答案。 小C是一個非常有自知之明的人&#xff0c…

微軟:軟件帝王的復興之路

可以說在過去的兩個月IT界所發生的一切都非同尋常&#xff0c;喬布斯辭職了&#xff0c;Google把Motorola并購了&#xff0c;微軟炫了一下Windows 8&#xff0c;還宣布開始用ARM了&#xff0c;Google開始和英特爾合作了&#xff0c;AT&T與T-Mobile的并購也在緊密鑼鼓進行中…

jdbc和odbc區別

ODBC(Open Database Connectivity&#xff0c;開放數據庫互連)是微軟公司開放服務結構(WOSA&#xff0c;Windows Open Services Architecture)中有關數據庫的一個組成部分&#xff0c;它建立了一組規范&#xff0c;并提供了一組對數據庫訪問的標準API&#xff08;應用程序編程接…

事務相關、不可重復讀與幻讀的區別

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 事務內嵌套事務&#xff1a; 1) 都用spring事務時&#xff0c;取決spring采用的事務的隔離級別。 這個默認隔離級別是與具體的數據…

onload事件

onload事件它只支持少量標簽<body>, <frame>, <iframe>, <img>, <input type"image">, <link>, <script>, <style> 不支持<div>,<p>標簽等 所以&#xff0c;在div使用onload事件時該怎么辦呢。。。轉載…

Eclipse GBK批量轉UTF-8插件(轉)

最近需要把Android項目轉Android Studio&#xff0c;由于之前是eclipse開發&#xff0c;而且坑爹的是編碼還是GBK的&#xff0c;轉到Android Studio中文都是亂碼&#xff0c;如果一個文件一個文件ctrlc的話&#xff0c;想想就累&#xff0c;幾經Google&#xff0c;發現一個很好…

網絡爬蟲--15.【糗事百科實戰】多線程實現

文章目錄一. Queue&#xff08;隊列對象&#xff09;二. 多線程示意圖三. 代碼示例一. Queue&#xff08;隊列對象&#xff09; Queue是python中的標準庫&#xff0c;可以直接import Queue引用;隊列是線程間最常用的交換數據的形式 python下多線程的思考 對于資源&#xff0…

淺談:國內軟件公司為何無法做大做強?

縱覽,國內比較大的軟件公司(以下統一簡稱"國軟"),清一色都是做政府項目的(他們能做大的原因我就不用說了吧),真正能做大的國軟又有幾家呢?這是為什么呢? 今天風吹就給大家簡單分析下: 1."作坊"式管理 "作坊"往往是效率最高的,國軟幾乎都是從作…

Java SE、Java EE、Java ME三者的區別

說得簡單點 Java SE 是做電腦上運行的軟件。 Java EE 是用來做網站的-&#xff08;我們常見的JSP技術&#xff09; Java ME 是做手機軟件的。 1. Java SE&#xff08;Java Platform&#xff0c;Standard Edition&#xff09;。Java SE 以前稱為 J2SE。它允許開發和部署在桌面、…

FileBeats安裝

FileBeats安裝 FileBeats官方下載鏈接&#xff1a; https://www.elastic.co/downloads/beats/filebeat 也可以直接使用以下命令下載&#xff08;文章下載目錄一概為/home/tools, 解壓后文件夾放到 /home/apps下&#xff09; wget https://artifacts.elastic.co/downloads/beats…

《程序員代碼面試指南》第三章 二叉樹問題 二叉樹節點間的最大距離問題

題目 二叉樹節點間的最大距離問題 java代碼 package com.lizhouwei.chapter3;/*** Description:二叉樹節點間的最大距離問題* Author: lizhouwei* CreateDate: 2018/4/16 19:33* Modify by:* ModifyDate:*/ public class Chapter3_20 {public int maxDistance(Node head) {int[…

MySQL中函數CONCAT及GROUP_CONCAT 對應oracle中的wm_concat

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 一、CONCAT&#xff08;&#xff09;函數 CONCAT&#xff08;&#xff09;函數用于將多個字符串連接成一個字符串。 使用數據表Info作為…

網絡爬蟲--16.BeautifulSoup4

文章目錄一. BeautifulSoup4二. 解析實例三. 四大對象種類1. Tag2. NavigableString3. BeautifulSoup4. Comment四. 遍歷文檔樹1.直接子節點 &#xff1a;.contents .children 屬性1). .contents2). .children2. 所有子孫節點: .descendants 屬性3. 節點內容: .string 屬性五. …

Intel MKL 多線程設置

對于多核程序&#xff0c;多線程對于程序的性能至關重要。 下面&#xff0c;我們將對Intel MKL 有關多線程方面的設置做一些介紹&#xff1a; 我們提到MKL 支持多線程&#xff0c;它包括的兩個概念&#xff1a; 1>MKL 是線程安全的&#xff1a; MKL在設計時&#xff0c;就保…