volatile不能保證原子性


1.看圖自己體會

2.體會不了就給你個小程序

package cs.util;

public class VolatileDemo {
   
	private volatile int count =0;
	
	
	public int getCount() {
		return this.count;
	}


	public void setCount() {
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		this.count++;
	}


	public static void main(String[] args) {
		// TODO Auto-generated method stub
		VolatileDemo demo=new VolatileDemo();
        for (int i = 0; i < 1000; i++) {
			new Thread(new Runnable() {
				
				@Override
				public void run() {
					// TODO Auto-generated method stub
					demo.setCount();
				}
			}).start();
		}
        while(Thread.activeCount()>1)
        {
        	Thread.yield();
        }
        System.out.println(demo.getCount());
	}

}

  輸出的結果是

不等於1000其實也不怪,這是由於count++其實是有三個操作組成 1.從主存拿共享變量count  2.進行count++ 3.把count寫進 內存

 

 本該為7的,最后卻為6,少了1,道理知道了吧

3.怎么解決沒有出現1000的情況呢 很簡單 有幾種做法 

一.可以加入 synchronized 

public void setCount() {
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
         //對count進行原子性操作 synchronized (this) { this.count++; } }

 二、使用jdk1.5推出的方法 具體修改如下

	//定義一個Lock 
        private Lock lock=new ReentrantLock();
	private volatile int count =0;
	
	public int getCount() {
		return this.count;
	}


	public void setCount() {
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
                //加鎖
		lock.lock();
		try {
			this.count++;
		} finally {
                //解鎖
			lock.unlock();
		}
		
		
		
	}        

  

 輸出結果就都為

 

 趕緊試一試吧

最后總結一下

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM