1. 程式人生 > >關於java對資源加鎖無效的問題

關於java對資源加鎖無效的問題

看程式設計思想一書,也寫了段程式碼,發現對static的資源加鎖無效,左思右想終於找出了原因,現貼出與大家分享。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class Source
{
	int i=0;
}
class Generator
{
	public static Integer i=0;
	public static Source source=new Source();
	public static Boolean isCancelled=false;
	public   int next()
	{
		/**
		 * 無效的資源加鎖
		 */
		synchronized(i)
		{
		i++;
		Thread.yield();
		i++;
		return i;
		}
		/**
		 * 有效的資源加鎖
		 */
//		synchronized(source)
//		{
//			source.i++;
//			Thread.yield();
//			source.i++;
//			return source.i;
//		}
		
	}
	
}
class Increase implements Runnable 
{
	int id;
	Generator gen;
	public Increase(Generator gen,int id)
	{
		this.gen=gen;
		this.id=id;
	}
	@Override
	public void run() {
		while(gen.isCancelled==false)
		{
			int val=gen.next();
			if(val%2!=0)
			{
				gen.isCancelled=true;
				print("#"+id+" error. val="+val);
			}
		}
		print("#"+id+" complete. gen:"+gen.next());
	//	print("#"+id+" complete. gen.i:"+gen.i.);
	}
	public static void print(Object obj)
	{
		System.out.println(obj);
	}
	
}
public class TestLock
{
	static ExecutorService exec = Executors.newCachedThreadPool();
	
	public static void main(String[] args){
		ExecutorService exec = Executors.newCachedThreadPool();
		Generator gen=new Generator();
	    for(int i = 0; i < 10; i++)
	      exec.execute(new Increase(new Generator(), i));
	    exec.shutdown();
		
	}
}

資源加鎖的關鍵是確定所加鎖的資源是否是唯一的,是否的分配的唯一記憶體地址的資源;
上面的無效加鎖原因是:static對基本型i 並沒有分配記憶體,而對於封裝了的資源source
則用new關鍵字進行了初始化,並擁有唯一記憶體,因此對source的加鎖才是對單一資源的加鎖;
而對於資源i ,10個執行緒有10個i到底是對誰加鎖呢?等於是沒有加鎖。
(有不恰當處,歡迎吐槽!!!)