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没有生效?
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没有生效?
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;
}
}
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();
}
}
//------------------- 方法结束。
}