首页 > 代码库 > java线程 同步临界区:thinking in java4 21.3.5

java线程 同步临界区:thinking in java4 21.3.5

java线程 同步临界区:thinking in java4 21.3.5

thinking in java 4免费下载:http://download.csdn.net/detail/liangrui1988/7580155

package org.rui.thread.critical;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;


/**
 * 临界区
 * 
 * 
 * 
 * Pair不是线程安全的,因为它的约束条件(虽然是任意的) 需要两个变量维护成相同的值。
 * 此外,如本章前面所述,自增加操作不是线程安全的,
 * 并且因为没有任何方法被标记为synchronized,所以不能保证一个pair对象在多线程程序中不会破坏.
 * @author lenovo
 *
 */
//org.rui.thread.critical.CriticalSection.java

class Pair
{
	private int x,y;
	public Pair(int x,int y)
	{
		 this.x=x;
		 this.y=y;
	}
	public Pair(){this(0,0);}
 
	public int getX() {
		return x;
	}
	public int getY() {
		return y;
	}
	public void incrementX(){x++;}
	public void incrementY(){y++;}
	public String toString()
	{
		return "x: "+x+" , y:"+y;
	}
	/////////////////PariValuesNotEqualException
	public class PariValuesNotEqualException extends RuntimeException
	{
		public PariValuesNotEqualException()
		{
			super("Pair values not equal:"+Pair.this);
		}
	}
	//任意变,两个变量必须是平等的
	//Arbitrary invariant --both variables must be equal:
	public void checkState()
	{
		if(x!=y)
		{
			throw new PariValuesNotEqualException();
		}
	}
}//Pair end



	//保护一对在一个线程安全的类
	//protect a pair inside a thread -safe class:
 abstract class PairManager
 {
	 AtomicInteger checkCounter=new AtomicInteger(0);
	 protected Pair p=new Pair();
	 private List<Pair> storage=Collections.synchronizedList(new ArrayList<Pair>());
	
	 public synchronized Pair getPair()
	 {
		 //复制的原始安全:
		 //Make a copy to keep the original safe:
		 return new Pair(p.getX(),p.getY());
	 }
	 //假设这是一个耗时的操作
	 //Assume this is a time consuming operation
	 protected void store(Pair p)
	 {
		 storage.add(p);
		 try {
			TimeUnit.MILLISECONDS.sleep(50);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	 }
	 //
	 public abstract void increment();
 }
 


//整个同步方法
//synchronize the entire method
class PairManager1 extends PairManager
{

	@Override
	public synchronized void increment()
	{
		p.incrementX();
		p.incrementY();
		store(getPair());
	}
}

//use a critical section: 使用临界区
class PairManager2 extends PairManager
{
  public void increment()
  {
	  Pair temp;
	  synchronized(this)
	  {
		  p.incrementX();
		  p.incrementY();
		  temp=getPair();
	  }
	  store(temp);
  }	
}

///操作者
class PairManipulator implements Runnable
{
    private PairManager pm;
    public PairManipulator(PairManager pm)
    {
    	this.pm=pm;
    }
	
	@Override
	public void run() 
	{
		while(true)
			pm.increment();		
	}	
	
	public String toString()
	{
		return "Pair: "+pm.getPair()+" checkCounter= "+pm.checkCounter.get();
	}
}
////PairChecker
class PairChecker implements Runnable
{
	private PairManager pm;
    public PairChecker(PairManager pm)
    {
    	this.pm=pm;
    }
	
	@Override
	public void run() {
		while(true)
		{
			pm.checkCounter.incrementAndGet();
			pm.getPair().checkState();
		}
	}
}



/////////////////////////////////////////////////////////
public class CriticalSection {
	//测试两种不同的方法
	//test the two defferent approaches
	static void testApproaches(PairManager pman1,PairManager pman2)
	{
		ExecutorService exec=Executors.newCachedThreadPool();
		PairManipulator pm1=new PairManipulator(pman1);
		PairManipulator pm2=new PairManipulator(pman2);
		
		PairChecker pcheck1=new PairChecker(pman1);
		PairChecker pcheck2=new PairChecker(pman2);
		
		exec.execute(pm1);
		exec.execute(pm2);
		exec.execute(pcheck1);
		exec.execute(pcheck2);
		
		try {
			TimeUnit.MILLISECONDS.sleep(500);
		} catch (InterruptedException e) {
			System.out.println("InterruptedException");
		}
		
		System.out.println("pm1:"+pm1+"\npm2:"+pm2);
		System.exit(0);
	}
	
	public static void main(String[] args) {
		PairManager pman1=new PairManager1(),
				    pman2=new PairManager2();
		
		testApproaches(pman1,pman2);
	}

}
/**output:(sample)
pm1:Pair: x: 8 , y:8 checkCounter= 674247
pm2:Pair: x: 8 , y:8 checkCounter= 5043736
 */

package org.rui.thread.critical;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
 * 你还可以使用显示的lock对象来创建临界区
 * 
 * 这里利用了CriticalSection.java的绝大部分,
 * 并创建了新的使用显式的lock对象的PairManger类型。
 * expliciPariManger2展示了如何使用Lock对象来创建临界区,而对store()的调用则在这个临界区的外部
 * @author lenovo
 *
 */

//////////////////////////


 class ExplicitPairManager1 extends PairManager {

	private Lock lock =new ReentrantLock();
	@Override
	public synchronized void increment() 
	{
		lock.lock();
		try{
			p.incrementX();
			p.incrementY();
			store(getPair());
		}finally{
			lock.unlock();
		}
	}
	
	

}



//use a critical section
	class ExplicitPairManager2 extends PairManager
	{
		private Lock lock =new ReentrantLock();
		@Override
		public void increment() {
			Pair temp=null;
			lock.lock();
			try{
				p.incrementX();
				p.incrementY();
				temp=getPair();
			}finally{
				lock.unlock();
			}
			
			store(temp);
		}
	}
/////////////////
public class ExplicitCriticalSection {

    public static void main(String[] args) 
    {
    	PairManager pman1=new PairManager1(),
			        pman2=new PairManager2();
	
    	CriticalSection.testApproaches(pman1,pman2);
	}
}
/**
 * output:
pm1:Pair: x: 10 , y:10 checkCounter= 195142
pm2:Pair: x: 11 , y:11 checkCounter= 4129459
 */