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

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

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 storage=Collections.synchronizedList(new ArrayList());

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

*/

Center

Center

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值