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

Posted ldxsuanfa

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
 */

技术图片技术图片

以上是关于java线程 同步临界区:thinking in java4 21.3.5的主要内容,如果未能解决你的问题,请参考以下文章

线程同步(windows平台):临界区

多线程多线程同步_Critical Section临界区

C++多线程同步技巧 --- 临界区

线程同步的几种方式

java 多线程怎么深入?

Java并发编程实战—–synchronized