首頁 >Java >java教程 >java中的Volatile關鍵字

java中的Volatile關鍵字

王林
王林原創
2024-08-30 16:19:44634瀏覽

java中Volatile的工作原理就像,如果我們希望我們的物件同時被多個執行緒訪問,我們可以使用這個關鍵字。這個關鍵字是使我們的類別、程式碼、方法執行緒安全的另一種方式,這意味著多個執行緒可以毫無問題地存取相同資源。我們的意思是違反關鍵字表明我們可以說多個執行緒將同時操作該變數值。

開始您的免費軟體開發課程

網頁開發、程式語言、軟體測試及其他

我們什麼時候在java中使用 volatile 關鍵字?

如果你想讓你的程式碼執行緒安全,你可以使用violations關鍵字。此外,它還提供同步功能;在這種情況下,這是一個不錯的選擇。

我們使用此關鍵字聲明的任何變數都不會進入快取;我們執行的所有操作,例如讀取和寫入,都將進入主記憶體。

class DemoSharedObject
{
static int sharedresources = 10;
}

以下一種導致資料不一致的情況:

我們有一個名為 DemoSharedObject 的類,假設有多個執行緒正在處理該類別並修改類別成員的值。因此,如果我們有多個執行緒在不同的處理器上執行,則每個執行緒都有自己的本機複製資源。因此,如果某個執行緒修改了公共資源的值,它的值不會很快反映到主記憶體中。但在這種情況下,我們的其他執行緒不知道共享資源的當前值,因此這將導致資料不一致的問題。

在java中,我們有兩種東西:同步語句和同步方法。

同步方法

在這種情況下,我們只需將synchronized關鍵字加入方法簽名即可。

文法:

public synchronized return_type method_name(){}

範例:

public class Demosynchronized {
private int c = 0;
public synchronized void method1() {
c++;
}
public synchronized void method2() {
c--;
}
public synchronized int method3() {
return c;
}
}

在上面的例子中,我們只是增加和減少計數器,但我們必須在方法中引入一個synchronized關鍵字,這樣就不會出現資料不一致的情況,並且所有執行緒都會收到更新後的值。

因此,當第一個執行緒在 method1() 上處​​理時,所有其他執行緒將被阻塞(掛起);在工作執行緒已經取得該物件的鎖之前,沒有其他執行緒可以存取相同物件。這就是他們避免數據不一致的方法。

此外,現在還有更多的事情是,每當執行緒完成對method1() 的操作,即完成執行一個方法時,它就會與其他執行緒建立關係,因此物件值或狀態的變化是可見的也到其他線程。

同步聲明

文法:

synchronized(){}

範例:

public void demo(String namestr) {
synchronized(this) {
lastName = namestr;
count++;
}
list.add(namestr);
}

在上面的範例中,我們有一個同步區塊將為我們管理資料。就像 namestr 將透過 demo() 方法同步一樣。也就是我們要同步的資料;我們只需要將它們放入這個區塊中即可。

因此,當我們有兩個執行緒在同一個物件上進行寫入和讀取時,這意味著我們有多個執行緒正在存取同一個物件以進行讀取和寫入,那麼我們應該使用Viruss關鍵字,因為它沒有為我們提供保證線程阻塞,除非並且直到其他線程停止執行,所以在這種情況下,我們應該進行同步,因為它為我們提供了一些比違反關鍵字更多的功能,例如:

它可以與方法一起使用,也可以與語句區塊一起使用,這意味著我們不需要同步整個方法;我們也可以在要同步的區塊內編寫程式碼。

當我們讀取或寫入 volatile 變數的值時,它們直接將值讀取或寫入主內存,這不是一個好的做法,而且與快取相比,這也很昂貴。因此,在使用 volatile 關鍵字之前請三思;它會直接影響你的表現。

假設我們有多個線程,它們不依賴彼此的回應,這意味著讀取和寫入是彼此獨立的,在這種情況下可以使用 volatile 關鍵字。但我們還有一個不適合使用 volatile 關鍵字的情況,如下所述:

Suppose thread has generated the first value of the volatile variable, and this current value will be used further to generate the new volatile variable values; in this case, this volatile keyword is not a good fit to generate the correct result; this condition will lead to a race condition were all thread going to read the same value but generate the new value for them and write the value to main memory and override each other values, so this will leads to the wrong result, or we can say data inconsistency issue, so here volatile keyword is not good enough to avoid this case we have to move to synchronization where we have to types to make our code synchronized, i.e. synchronized method and synchronized statement.

Example

Code:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TvvApplication {
private static final Logger LOGGER = LoggerFactory.getLogger(TvvApplication.class);
private static final Object aclock = new Object();
private static final Object aclock1 = new Object();
private static volatile int MY_INT = 0;
public static void main(String[] args) {
System.out.println("without block");
System.out.println("with block calling static method :: ");
testBlock();
}
static void testBlock1() {
synchronized (aclock1) {
MY_INT = MY_INT + 1;
System.out.println( Thread.currentThread().getName() +"new lock we create and printing voilatile value using block for block one:: "+ MY_INT);
}
}
static void testBlock() {
synchronized (aclock) {
MY_INT = MY_INT + 1;
System.out.println( Thread.currentThread().getName() +"new lock we create and printing voilatile value using block for block two:: "+ MY_INT);
}
}
}

Output :

<img src="https://img.php.cn/upload/article/000/000/000/172500598784733.png" alt="java中的Volatile關鍵字" >

Conclusion

So this can provide thread safety when data does not depend on each other; if data depends, we should go for synchronization.

以上是java中的Volatile關鍵字的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn