在Java編程中,多線程是非常常見的,而線程間共享變量的情況也經常會遇到。在這種情況下,就需要考慮到數據的同步。Java提供了兩種方式來保證線程安全:volatile和synchronized。
volatile關鍵字
volatile關鍵字用于保證變量的可見性。當一個變量被聲明為volatile時,如果一個線程修改了這個變量的值,那么其他線程會立即看到這個變量的修改。volatile關鍵字的作用是禁止指令重排序,保證了代碼的執行順序。
public class TestVolatile { private volatile boolean flag = false; public void setFlag(boolean flag) { this.flag = flag; } public void run() { while(!flag) { // do something } // do something when flag is true } }
上述代碼中,flag變量被聲明為volatile。如果在另一個線程中調用setFlag(true)方法,那么在當前線程中的flag變量會立即被更新,從而讓當前線程退出while循環。
synchronized關鍵字
synchronized關鍵字用于保證同一個時刻只能有一個線程訪問某個對象或變量。它包括兩種使用方式:同步方法和同步塊。
1. 同步方法:
public class TestSync { private synchronized void synMethod() { // do something } }
在上述代碼中,synMethod方法被聲明為synchronized。當線程訪問該方法時,會獲取該對象的鎖,其他線程需要等待該線程釋放該對象的鎖才能訪問該方法。
2. 同步塊:
public class TestSync { private Object lock = new Object(); public void synBlock() { synchronized(lock) { // do something } } }
在上述代碼中,synBlock方法中使用了同步塊,在同步塊中使用了lock對象來同步。該方法中的同步塊只有獲取了lock對象的鎖才能訪問,在訪問完同步塊后,會釋放lock對象的鎖。
總的來說,volatile關鍵字用于保證變量的可見性,而synchronized關鍵字用于保證同一個時刻只能有一個線程訪問某個對象或變量,從而保證線程安全。