這篇文章主要介紹了java中volatile和synchronized的區別與聯繫的相關資料,希望透過本文能幫助到大家,讓大家理解這部分內容,需要的朋友可以參考下
#java中volatile和synchronized的區別與聯繫
這個可能是最好的對比volatile和synchronized作用的文章了。 volatile是一個變數修飾符,而synchronized是一個方法或區塊的修飾符。所以我們使用這兩個關鍵字來指定三種簡單的訪問變數的方式
int i1; int geti1() {return i1;} volatile int i2; int geti2() {return i2;} int i3; synchronized int geti3() {return i3;}
geti1()在目前執行緒中立即取得在i1變量中的值。執行緒可以獲得變數的本地拷貝,而所獲得的變數的值並不一定與其他執行緒所獲得的值相同。特別是,如果其他的執行緒修改了i1的值,那麼目前執行緒所獲得的i1的值可能與修改後的值有所差別。實際上,Java有一個主記憶體的機制,使用一個主記憶體來保存變數目前的正確的值。執行緒將變數的值拷貝到自己獨立的記憶體中,而這些執行緒的記憶體拷貝可能與主記憶體中的值不同。所以實際當中可能發生這樣的情況,在主記憶體中i1的值為1,線程1和線程2都更改了i1,但是卻沒把更新的值傳回給主內存或其他線程中,那麼可能在線程1中i1的值為2,線程2中i1的值卻為3。
另一方面,geti2()可以有效的從主記憶體中取得i2的值。一個volatile類型的變數不允許執行緒從主記憶體中將變數的值拷貝到自己的儲存空間。因此,一個聲明為volatile類型的變量將在所有的線程中同步的獲得數據,不論你在任何線程中更改了變量,其他的線程將立即得到同樣的結果。由於執行緒存取或更改自己的資料拷貝有更高的效率,所以volatile類型變數在效能上有所消耗。
那麼如果volatile變數已經可以讓資料在執行緒間同步,那麼synchronizes用來幹嘛?兩者有兩方面的不同。首先,synchronized取得和釋放由監聽器控制的鎖,如果兩個執行緒都使用一個監聽器(即相同物件鎖),那麼監聽器可以強制在一個時刻只有一個執行緒能處理程式碼區塊,這是最一般的同步。另外,synchronized還能讓記憶體同步。在實際當中,synchronized使得所有的線程內存與主內存相同步。所以geti3()的執行過程如下:
1. 執行緒從監聽器取得物件的鎖定。 (這裡假設監聽器非鎖,否則線程只有等到監聽器解鎖才能獲取對象鎖)
#2. 線程內存更新所有的變量,也就是說他將讀取主內存中的變量使自己的變數保證有效。 (JVM會使用一個「髒」標誌來最優化過程,使得僅僅具有「髒」標誌變數被更新。詳細的情況查詢JAVA規範的17.9)
#3. 程式碼區塊被執行(在這個範例中,設定回傳值為剛剛從主記憶體重置的i3目前的值。但是這個例子中geti3()沒有什麼變化。
5. 執行緒釋放物件的鎖定給監聽器。
所以volatile只能在線程記憶體和主記憶體之間同步一個變數的值,而synchronized則同步在執行緒記憶體和主記憶體之間的所有變數的值,並且透過鎖定和釋放監聽器來實現。顯然,synchronized在性能上將比volatile更加有所消耗。
關於兩者的區別
1.volatile本質是在告訴jvm當前變數在暫存器(工作記憶體)中的值是不確定的,需要從主記憶體讀取;synchronized則是鎖定目前變量,只有當前執行緒可以存取該變量,其他執行緒被阻塞住。
2.volatile只能使用在變數層級;synchronized則可以使用在變數、方法、和類別層級的
3.
volatile僅能實現變數的修改可見性,不能保證原子性
4.volatile不會造成執行緒的阻塞;synchronized可能會造成線程的阻塞。
5.volatile標記的變數不會被編譯器最佳化;synchronized標記的變數可以被編譯器最佳化
紅色字體部分的原因如下:
線程A修改了變數還沒結束時,另外的線程B可以看到已修改的值,而且可以修改這個變數,而不用等待A釋放鎖定,因為Volatile 變量沒上鎖
以上是Java中synchronized與volatile的差異與聯繫的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Java中volatile变量保证线程安全的方法:可见性:确保一个线程对volatile变量的修改立即对其他线程可见。原子性:确保对volatile变量的某些操作(如写入、读取和比较交换)是不可分割的,不会被其他线程打断。

Java中volatile关键字的作用及应用场景详解一、volatile关键字的作用在Java中,volatile关键字用于标识一个变量在多个线程之间可见,即保证可见性。具体来说,当一个变量被声明为volatile时,任何对该变量的修改都会立即被其他线程所知晓。二、volatile关键字的应用场景状态标志volatile关键字适用于一些状态标志的场景,例如一

一、通过程序看现象在开始为大家讲解Java多线程缓存模型之前,我们先看下面的这一段代码。这段代码的逻辑很简单:主线程启动了两个子线程,一个线程1、一个线程2。线程1先执行,sleep睡眠2秒钟之后线程2执行。两个线程使用到了一个共享变量shareFlag,初始值为false。如果shareFlag一直等于false,线程1将一直处于死循环状态,所以我们在线程2中将shareFlag设置为true。publicclassVolatileTest{publicstaticbooleanshareFl

C++是一门强类型语言,严格限制了变量的类型转换,但是在某些情况下,我们可能需要对volatile类型对象进行类型转换,特别是在嵌入式开发中,我们常常需要访问硬件寄存器,而这些寄存器通常都是volatile类型的。然而,由于volatile类型的对象具有特殊的语义,所以C++编译器会对其进行一些特殊的限制,这就导致了“不能调用从volatile类型转换的成员

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于多线程的相关问题,包括了线程安装、线程加锁与线程不安全的原因、线程安全的标准类等等内容,希望对大家有帮助。

本篇文章给大家带来了关于Java的相关知识,其中主要介绍了关于关键字中this和super的相关问题,以及他们的一些区别,下面一起来看一下,希望对大家有帮助。

了解Java中volatile的作用:保证多线程间数据的可见性和有序性,需要具体代码示例在Java多线程编程中,为了确保多个线程之间的数据同步,我们常常需要使用volatile关键字。volatile关键字可以保证可见性和有序性,确保多个线程对某个变量的读写操作是正确的。一、可见性在多线程环境下,如果一个线程对某个共享变量进行修改,那么其他线程是否能够立即看

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于设计模式的相关问题,主要将装饰器模式的相关内容,指在不改变现有对象结构的情况下,动态地给该对象增加一些职责的模式,希望对大家有帮助。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SublimeText3漢化版
中文版,非常好用

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

Dreamweaver CS6
視覺化網頁開發工具

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中