国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

java多線程編程之慎重使用volatile關鍵字

2019-11-26 15:44:06
字體:
來源:轉載
供稿:網友

volatile關鍵字相信了解Java多線程的讀者都很清楚它的作用。volatile關鍵字用于聲明簡單類型變量,如int、float、boolean等數據類型。如果這些簡單數據類型聲明為volatile,對它們的操作就會變成原子級別的。但這有一定的限制。例如,下面的例子中的n就不是原子級別的:

復制代碼 代碼如下:

package mythread;

public class JoinThread extends Thread
{
public static volatile int n = 0;
public void run()
{
for (int i = 0; i < 10; i++)
try
{
n = n + 1;
sleep(3); // 為了使運行結果更隨機,延遲3毫秒

}
catch (Exception e)
{
}
}

public static void main(String[] args) throws Exception
{

Thread threads[] = new Thread[100];
for (int i = 0; i < threads.length; i++)
// 建立100個線程
threads[i] = new JoinThread();
for (int i = 0; i < threads.length; i++)
// 運行剛才建立的100個線程
threads[i].start();
for (int i = 0; i < threads.length; i++)
// 100個線程都執行完后繼續
threads[i].join();
System.out.println("n=" + JoinThread.n);
}
}

如果對n的操作是原子級別的,最后輸出的結果應該為n=1000,而在執行上面積代碼時,很多時侯輸出的n都小于1000,這說明n=n+1不是原子級別的操作。原因是聲明為volatile的簡單變量如果當前值由該變量以前的值相關,那么volatile關鍵字不起作用,也就是說如下的表達式都不是原子操作:

復制代碼 代碼如下:

n = n + 1;
n++;

如果要想使這種情況變成原子操作,需要使用synchronized關鍵字,如上的代碼可以改成如下的形式:

復制代碼 代碼如下:

package mythread;

public class JoinThread extends Thread
{
public static int n = 0;

public static synchronized void inc()
{
n++;
}
public void run()
{
for (int i = 0; i < 10; i++)
try
{
inc(); // n = n + 1 改成了 inc();
sleep(3); // 為了使運行結果更隨機,延遲3毫秒

}
catch (Exception e)
{
}
}

public static void main(String[] args) throws Exception
{

Thread threads[] = new Thread[100];
for (int i = 0; i < threads.length; i++)
// 建立100個線程
threads[i] = new JoinThread();
for (int i = 0; i < threads.length; i++)
// 運行剛才建立的100個線程
threads[i].start();
for (int i = 0; i < threads.length; i++)
// 100個線程都執行完后繼續
threads[i].join();
System.out.println("n=" + JoinThread.n);
}
}

上面的代碼將n=n+1改成了inc(),其中inc方法使用了synchronized關鍵字進行方法同步。因此,在使用volatile關鍵字時要慎重,并不是只要簡單類型變量使用volatile修飾,對這個變量的所有操作都是原來操作,當變量的值由自身的上一個決定時,如n=n+1、n++等,volatile關鍵字將失效,只有當變量的值和自身上一個值無關時對該變量的操作才是原子級別的,如n = m + 1,這個就是原級別的。所以在使用volatile關鍵時一定要謹慎,如果自己沒有把握,可以使用synchronized來代替volatile。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 镇宁| 临泽县| 胶南市| 平塘县| 峨边| 额敏县| 麻江县| 松阳县| 景东| 招远市| 常德市| 东乌珠穆沁旗| 黔西县| 长阳| 黑河市| 宣城市| 沅江市| 东乡县| 竹溪县| 定南县| 通辽市| 策勒县| 涪陵区| 泉州市| 乌鲁木齐市| 江陵县| 琼结县| 舞钢市| 蒲城县| 伊川县| 铜陵市| 利津县| 清丰县| 竹溪县| 太湖县| 贵南县| 扶余县| 聂荣县| 磴口县| 西峡县| 益阳市|