Java 併發之共享變量

                    同步訪問共享的可變數據

    同步的意義有兩個方面,之前一直以爲只是爲了操作的互斥性,保持狀態一致,理解太淺顯,需要深入研究。

            一、保持對象狀態一致性,即同步可以阻止一個線程看到對象處於不一致的狀態中,當一個線程訪問同步對

象時,可阻止其他線程對該對象進行訪問,從而觀察到對象內部不一致的狀態;

    二、保證進入同步方法或者同步代碼塊的每個線程,都看到由同一個鎖保護的之前的所有修改。

             示例一、

     如果期望1s中後,backgroudThread線程能夠正常退出,在某些機器上可能會失敗,因爲主進程將stopRequested設置爲true的狀態,backgroudThread不一定能及時看到。

    public class StopThread 
    {
	private static boolean stopRequested;
	
//	public static synchronized void requestStop()
//	{
//		stopRequested = true;
//	}
//	
//	public static synchronized boolean stopRequested()
//	{
//		return stopRequested;
//	}
	
	public static void main(String[] args) throws InterruptedException
	{
		Thread backgroudThread = new Thread(new Runnable()
		{
			public void run()
			{
				int i = 0;
				while(!stopRequested)
				{
					i++;
					System.out.println("i: " + i);
				}
				System.out.println("out!!!");
			}
		});
		
		backgroudThread.start();
		
		TimeUnit.SECONDS.sleep(1);
		
		//requestStop();
		stopRequested = true;
	}

    }


 

        示例二、

   用同步來解決這個問題,通過同步,backgroudThread線程每次讀的狀態值stopRequested都能保證是其他線程已經修改過的。

    public class StopThread 
    {
	private static boolean stopRequested;
	
	public static synchronized void requestStop()
	{
		stopRequested = true;
	}
	
	public static synchronized boolean stopRequested()
	{
		return stopRequested;
	}
	
	public static void main(String[] args) throws InterruptedException
	{
		Thread backgroudThread = new Thread(new Runnable()
		{
			public void run()
			{
				int i = 0;
				while(!stopRequested())
				{
					i++;
					System.out.println("i: " + i);
				}
				System.out.println("out!!!");
			}
		});
		
		backgroudThread.start();
		
		TimeUnit.SECONDS.sleep(1);
		
		requestStop();
	}

    }


         另外,volatile也可以保證它所修飾的對象的修改都能被立即寫入主內存,從而達到同步的效果,如果只需要線程之間通信,而不用互斥,volatile是一種可以接受的同步形式,但使用要謹慎。

   java語言規範保證所有基本數據類型的讀寫操作都是原子操作,long和double除外,因爲64位數值會被分成兩個32位值來操作。

          最好的方法:要麼共享不可變的數據,要麼壓根不共享,即將可變數據限制在單個線程中。

   注:java內存模型(JMM),深入理解java內存模型

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章