在Java中實(shí)現(xiàn)可見性(visibility)的主要方法詳解
可見性 visibility
在Java中,實(shí)現(xiàn)可見性(visibility)的主要方法是使用關(guān)鍵字volatile和使用鎖(如synchronized關(guān)鍵字或 java.util.concurrent包中的鎖)來確保對共享變量的修改在多線程環(huán)境中能夠正確地被其他線程所觀察到。
下面詳細(xì)說明這兩種方法,并附帶代碼演示。
1.使用volatile關(guān)鍵字:
volatile是一種輕量級的同步機(jī)制,用于告訴JVM對被修飾的變量不進(jìn)行緩存,直接從主內(nèi)存中讀取和寫入數(shù)據(jù)。
這樣可以確保當(dāng)一個線程修改了變量的值時(shí),其他線程能夠立即看到這個變化,而不是使用緩存中的舊值。
public class VolatileVisibilityExample {
private volatile boolean flag = false;
public void setFlag(boolean value) {
flag = value;
}
public void checkFlag() {
while (!flag) {
// Busy waiting until the flag becomes true
}
System.out.println("Flag is now true!");
}
public static void main(String[] args) {
VolatileVisibilityExample example = new VolatileVisibilityExample();
new Thread(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
example.setFlag(true);
}).start();
new Thread(() -> {
example.checkFlag();
}).start();
}
}在上面的例子中,我們創(chuàng)建了一個VolatileVisibilityExample類,其中的flag變量被聲明為volatile。
第一個線程在啟動后會等待1秒鐘然后將flag設(shè)置為true,而第二個線程在flag變?yōu)閠rue之前會一直進(jìn)行忙等待(busy waiting)。
由于flag是volatile的,第二個線程能夠看到第一個線程對flag的修改,并在flag變?yōu)閠rue時(shí)結(jié)束忙等待。
2.使用鎖:
另一種實(shí)現(xiàn)可見性的方法是使用鎖,通過synchronized關(guān)鍵字或者java.util.concurrent包中的鎖機(jī)制來保護(hù)對共享變量的訪問。
public class LockVisibilityExample {
private boolean flag = false;
private final Object lock = new Object();
public void setFlag(boolean value) {
synchronized (lock) {
flag = value;
}
}
public void checkFlag() {
synchronized (lock) {
while (!flag) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println("Flag is now true!");
}
public static void main(String[] args) {
LockVisibilityExample example = new LockVisibilityExample();
new Thread(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
example.setFlag(true);
synchronized (example.lock) {
example.lock.notifyAll();
}
}).start();
new Thread(() -> {
example.checkFlag();
}).start();
}
}在上面的例子中,我們創(chuàng)建了一個LockVisibilityExample類,其中使用了一個名為lock的對象作為鎖。
在setFlag和checkFlag方法中,我們使用synchronized關(guān)鍵字來保護(hù)對flag的訪問。
第一個線程設(shè)置flag為true并通過synchronized塊的notifyAll()方法通知第二個線程,而第二個線程則在flag變?yōu)閠rue之前一直等待,并在被通知后結(jié)束等待。
這兩種方法都可以實(shí)現(xiàn)可見性,但使用volatile更為簡單和輕量級。
然而,在某些情況下,使用鎖可能會更有優(yōu)勢,例如需要進(jìn)行更復(fù)雜的操作或需要更精細(xì)地控制對共享資源的訪問。
到此這篇關(guān)于在Java中實(shí)現(xiàn)可見性(visibility)的主要方法詳解的文章就介紹到這了,更多相關(guān)Java中實(shí)現(xiàn)可見性內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java Swing實(shí)現(xiàn)餐廳點(diǎn)餐系統(tǒng)源碼(收藏版)
這篇文章主要介紹了Java Swing實(shí)現(xiàn)餐廳點(diǎn)餐系統(tǒng)源碼,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02
SpringBoot項(xiàng)目實(shí)現(xiàn)分布式日志鏈路追蹤
這篇文章主要給大家介紹了Spring Boot項(xiàng)目如何實(shí)現(xiàn)分布式日志鏈路追蹤,文中通過代碼示例給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-07-07
Java實(shí)現(xiàn)DelayQueue延遲隊(duì)列示例代碼
Java中的DelayQueue是一個特殊的隊(duì)列,它只允許在指定的延遲時(shí)間之后才能從隊(duì)列中取出元素,這篇文章主要給大家介紹了關(guān)于Java實(shí)現(xiàn)DelayQueue延遲隊(duì)列的相關(guān)資料,需要的朋友可以參考下2025-07-07
SpringBoot基于FFmpeg實(shí)現(xiàn)壓縮視頻切片為m3u8
本文介紹了一個使用FFmpeg將MP4視頻壓縮切片為HLS格式M3U8文件的Java工具類,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2026-02-02

