併發程式設計 08安全發布物件之發布與逸出

2021-09-11 04:19:56 字數 2067 閱讀 4849

小結**

發布物件:使乙個物件能夠被當前範圍之外的**所使用,日常開發中比較常見的比如通過類的非私有方法返回物件的引用,或者通過公有的靜態變數發布物件等都屬於發布物件

物件逸出: 首先需要明確的是物件逸出是一種錯誤的發布方式當乙個物件還沒有構造完成時,就使它被其他執行緒所見

package com.artisan.example.publish;

import com.artisan.anno.notthreadsafe;

import lombok.extern.slf4j.slf4j;

@slf4j

@notthreadsafe

public

class

unsafepublishobjectdemo

public

static

void

main

(string[

] args)

",name)

;// 假設有第二個執行緒去修改name屬性的值

string name2 = unsafepublishobjectdemo.

getname()

; name2 =

"小工匠"

; log.

info

("name:{}"

,name2);}

}

上面的**裡,通過new物件初始化了unsafepublishobjectdemo物件。然後呼叫getname()方法獲取到了私有屬性的引用,這樣就可以在其他任何執行緒中,修改該屬性的值。這樣將會導致我們在其他執行緒中,獲取該屬性的值時是不確定的,因為並不能得知該屬性的值是否已被其他執行緒所修改過,所以這就是不安全的物件發布。

package com.artisan.example.publish;

import com.artisan.anno.notrecommand;

import com.artisan.anno.notthreadsafe;

import lombok.extern.slf4j.slf4j;

/** *

* 物件逸出示例,在物件構造完成之前,不可以將其發布

* @author yangshangwei

* */

@slf4j

@notthreadsafe

@notrecommand

public

class

objectescapedemo

private

class

innerclass

", objectescapedemo.

this

.thiscanbeescape);}

}public

static

void

main

(string[

] args)

}

上述**中,內部類的構造器裡包含了對封裝例項的隱含引用,這樣在物件沒有被正確構造完成之前就會被發布,由此會導致不安全的因素在裡面。其中乙個就是導致this引用在構造期間逸出的錯誤,它是在建構函式構造過程中啟動了乙個執行緒,無論是顯式啟動還是隱式啟動,都會造成this引用的逸出

新執行緒總會在所屬物件構造完畢之前就已經看到它了,所以如果要在建構函式中建立執行緒,那麼不要啟動它,而是應該採用乙個專有的start,或是其他初始化的方式統一啟動執行緒。

這裡其實我們可以使用工廠方法和私有建構函式來完成物件建立和***的註冊等等來避免不正確的發布。

不正確的發布可變物件導致的兩種錯誤:

併發程式設計(七) 安全發布物件

發布物件是指使乙個物件能夠被當前範圍之外的 所使用 物件逸出是一種錯誤的發布,指當乙個物件還沒有構造完成時,就使它被其他執行緒所見 slf4j public class escape private class innerclass escape.this thiscanbeescape publi...

併發學習(十) 安全物件發布

平時我們建立的物件往往不會考慮到安全物件的概念,這可能比較陌生,但是你面試的時候面試官很喜歡問你執行緒安全的單例模式,而這就是相關的知識點 發布 使物件能夠在除了當前作用域之外的地方使用 最常用的方法 將物件的引用儲存到乙個公有的靜態變數中,讓任何類和執行緒都能看到該物件。逸出 某個物件不應該被發布...

(二)Java併發學習筆記 安全發布物件

上邊關於逸出的概念講述的很是模糊,下面列舉幾個逸出的示例。通過靜態變數引用逸出 public static setknownsecrets public void initialize 上邊 示例中,呼叫initialize方法,發布了knowsecrets物件。當你向knowsecrets中新增乙...