package thread.block;import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;//使用同步控制块 比 整个方法同步效率高很多
 
public class CriticalSection {

static void testApproaches(PairManager pman1, PairManager pman2) {
ExecutorService exec=Executors.newCachedThreadPool();  
// PairManipulator pm1=new PairManipulator(pman1);  
PairManipulator pm2=new PairManipulator(pman2); 
//PairCheck pcheck1=new PairCheck(pman1);
PairCheck pcheck2=new PairCheck(pman2); 
//exec.execute(pm1);
exec.execute(pm2); 
    //exec.execute(pcheck1); 
   exec.execute(pcheck2); 
try {
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("pm1: "+ "" +"\npm2: "+pm2);
System.exit(0);   }
public static void main(String[] args) {
PairManager pman1=new PairManager1();   
PairManager pman2=new ExplicitPairManager2(); 
testApproaches(pman1, pman2); 
}
}class Pair {
private int x, y; public int getX() {
return x;
} public void incrementX() {
x++;
} public int getY() {
return y;
} public void incrementY() {
y++;
} public Pair(int x, int y) {
this.x = x;
this.y = y;
} public Pair() {
this(0, 0);
} public String toString() {
return "x: " + x + ",y " + y;
} public void checkState() { 
if (x != y) {
throw new PairValuesnotEqualException();
}
} public class PairValuesnotEqualException extends RuntimeException {
public PairValuesnotEqualException() {
super("Pair values not equal : " + Pair.this);
}
}
}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() {  
//System.out.println(p.getX()+"="+p.getY());
return new Pair(p.getX(), p.getY());
} protected void store(Pair p) {
storage.add(p);
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} public abstract void increment();
}class PairManager1 extends PairManager {
public synchronized void increment() {
p.incrementX();
p.incrementY();
store(getPair()); 
}}class PairManager2 extends PairManager {
public void increment() {
Pair temp;
synchronized (this) {
p.incrementX();
p.incrementY();
temp = getPair();   
}
store(temp);
}
}
class ExplicitPairManager2 extends PairManager{
private Lock lock=new ReentrantLock();    //为什么lock没有生效
@Override
public  void increment() {
Pair temp;
lock.lock();            
try {

p.incrementX();
p.incrementY();
temp=getPair();

}  finally{
lock.unlock();
}
store(temp);

}

}
class PairManipulator implements Runnable {
private PairManager pm; 
public PairManipulator(PairManager pm) { this.pm = pm;
} public void run() {
while (true) {
// System.out.println("********************8pmPulator"+pm);
pm.increment();
}
} public String toString() {
return "Pair : " + pm.getPair() + " checkCounter = "
+ pm.checkCounter.get();
}
}class PairCheck implements Runnable {
private PairManager pm; public void run() {
while(true){
// System.out.println("pmCheck:"+pm);
pm.checkCounter.incrementAndGet();
pm.getPair().checkState();
}
} public PairCheck(PairManager pm) {
  this.pm = pm;
}

为什么在ExplicitPairManager2 类中的lock没有生效?

解决方案 »

  1.   

    没看懂,我都没有看到有多线程,不知道用锁是什么意思,可能我没有看明白,你代码又没有注释,又不对齐,人家怎么看啊。你只是实现Runnable,没有看到用thread启动,只能是单线程运行的啊。
      

  2.   

    package thread.block;import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    import java.util.concurrent.Executor;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.atomic.AtomicInteger;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;//使用同步控制块 比 整个方法同步效率高很多public class CriticalSection { static void testApproaches(PairManager pman1, PairManager pman2) {
    ExecutorService exec = Executors.newCachedThreadPool();
     PairManipulator pm1=new PairManipulator(pman1);
    PairManipulator pm2 = new PairManipulator(pman2);
     PairCheck pcheck1=new PairCheck(pman1);
    PairCheck pcheck2 = new PairCheck(pman2);
    //  exec.execute(pm1);
    exec.execute(pm2);    //线程启动
    //  exec.execute(pcheck1);
    exec.execute(pcheck2); //线程启动
    try {
    TimeUnit.MILLISECONDS.sleep(500);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    System.out.println("pm1: " + "" + "\npm2: " + pm2);
    System.exit(0); } public static void main(String[] args) {
     
    PairManager pman2 = new ExplicitPairManager2();
    testApproaches(null, pman2);
    }

    /**
     * x,y必须相同
     * x,y 不相同PairValuesnotEqualException 类将抛出异常
     * @author Administrator
     *
     */
    class Pair {
    private int x, y; public int getX() {
    return x;
    } public void incrementX() {
    x++;
    } public int getY() {
    return y;
    } public void incrementY() {
    y++;
    } public Pair(int x, int y) {
    this.x = x;
    this.y = y;
    } public Pair() {
    this(0, 0);
    } public String toString() {
    return "x: " + x + ",y " + y;
    } public void checkState() {
    if (x != y) {
    throw new PairValuesnotEqualException();
    }
    } public class PairValuesnotEqualException extends RuntimeException {
    public PairValuesnotEqualException() {
    super("Pair values not equal : " + Pair.this);
    }
    }

    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() {
    // System.out.println(p.getX()+"="+p.getY());
    return new Pair(p.getX(), p.getY());     //实例化 pair
    } protected void store(Pair p) {
    storage.add(p);               // 将pair添加到list里面
    try {
    TimeUnit.MILLISECONDS.sleep(10);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    } public abstract void increment();

    class ExplicitPairManager2 extends PairManager {
    //将x,y 同时加一 
    //并将pair对象放入 list
    private Lock lock = new ReentrantLock(); // 为什么lock没有生效 public void increment() {
    Pair temp;
    lock.lock();
    try { p.incrementX();
    p.incrementY();
    temp = getPair(); } finally {
    lock.unlock();
    }
    store(temp); }}class PairManipulator implements Runnable {
    private PairManager pm; public PairManipulator(PairManager pm) { this.pm = pm;
    } public void run() {
    while (true) {
    // System.out.println("********************8pmPulator"+pm);
    pm.increment();
    }
    } public String toString() {
    return "Pair : " + pm.getPair() + " checkCounter = "
    + pm.checkCounter.get();
    }
    }class PairCheck implements Runnable {
    private PairManager pm; public void run() {
    while (true) {
    // System.out.println("pmCheck:"+pm);
    pm.checkCounter.incrementAndGet();
    pm.getPair().checkState();
    }
    } public PairCheck(PairManager pm) {
    this.pm = pm;
    }
    }
      

  3.   

    个人浅见:
    1 下面这段代码虽然加了同步,但不起作用. 只有一个线程会调用此方法,不存在同步问题,会产生 x,y不一致的情况。
     public synchronized Pair getPair() {
            //System.out.println(p.getX()+"="+p.getY());
            return new Pair(p.getX(), p.getY());     //实例化 pair
        }
    2 建议将此方法改为抽象,在其子类里具体实现,用lock对象加锁,与increment()同步。increment()方法没有执行完,不会执行getPair().
      代码如下: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() {
            //System.out.println(p.getX()+"="+p.getY());
            return new Pair(p.getX(), p.getY());     //实例化 pair
        }*/
        //------------------改为抽象方法
        //
        public abstract Pair getPair();    protected void store(Pair p) {
            storage.add(p);               // 将pair添加到list里面
            try {
                TimeUnit.MILLISECONDS.sleep(10);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }    public abstract void increment();

    class ExplicitPairManager2 extends PairManager {
        //将x,y 同时加一 
        //并将pair对象放入 list
        private Lock lock = new ReentrantLock(); // 为什么lock没有生效    public void increment() {
            Pair temp;
            lock.lock();
            try {
                p.incrementX();
                p.incrementY();
                temp = getPair();
            } finally {
                lock.unlock();
            }
            store(temp);
        }
        //------------------- 子类实现并同步. 用lock对象。
        //-------------------
        public Pair getPair(){
           lock.lock();
           try{
                return new Pair(p.getX(), p.getY());
           }finally{
                lock.unlock();
           }
        }
        //------------------- 方法结束。
    }