互斥锁-同步

 在近期一个Java项目里,我们使用Struts2来做MVC框架,有几个action里使用了static变量来做数据缓存,只有数据库有更新时才读取数据,减少对数据库的访问次数。
      首先需要理解的是, webwork和structs2都采用多线程处理action的,每用户请求将创建一个action对象;那么,这定义在action里的static变量将被多线程并发访问,这就需要同步控制。Java语言使用synchronized关键来进行处理,发现java组程序员对此理解不深或不全面,其实也不奇怪,他们大多数时间在做B/S结构的web系统,接触的机会并不多;作为一个老C++程序员,既然碰到了这个问题,就干脆把Java、Unix/Linux Pthread库,Win32三方面,对互斥锁的支持说明一下,主要是怎么理解和使用。
      这篇先说Java, 理解synchronized的作用,一定要抓住两点:
      1)  对象上的锁:一定要注意同一个对象才有效;
      2)  类范围上的锁:所有对象都有效。
      至于两种使用方法,下面的例子不厌其烦地列举正确和错误使用两种情况,完全理解了下面测试程序输出结果,你就及格了:

 --------------------------------------------------------------------------------------------------------------------------------------    
/**
 *
 * @author liangbing
 * @date Dec 26, 2008
 */
public class SyncObject {
 
 private byte[] lock = new byte[0]; // 特殊的instance变量, 同步控制作用
 
 private static byte[] allLock = new byte[0]; // 特殊的static变量, 同步控制作用

 public synchronized void doA(String str) throws InterruptedException {
  System.out.println("doA():: start:" + str);
  Thread.sleep(2000);
  System.out.println("doA():: end:" + str);
 }
 
 public synchronized void doB(String str) throws InterruptedException {
  System.out.println("doB():: start:" + str);
  Thread.sleep(2000);
  System.out.println("doB():: end:" + str);
 }
 
 public void doC(String str) throws InterruptedException {
  synchronized (this) {
   System.out.println("doC():: start:" + str);
   Thread.sleep(2000);
   System.out.println("doC():: end:" + str);
  }
 }
 
 public void doD(String str, Object locks) throws InterruptedException {
  synchronized(locks) {
   System.out.println("doD():: start:" + str);
   Thread.sleep(2000);
   System.out.println("doD():: end:" + str);
  }
 }
 
 public void doE(String str) throws InterruptedException {
  synchronized(lock) {
   System.out.println("doE():: start:" + str);
   Thread.sleep(2000);
   System.out.println("doE():: end:" + str);
  }
 }
 
 public synchronized static void doF(String str) throws InterruptedException {
  System.out.println("doF():: start:" + str);
  Thread.sleep(2000);
  System.out.println("doF():: end:" + str);
 }
 
 public void doG(String str) throws InterruptedException {
  synchronized (SyncObject.class) {
   System.out.println("doG():: start:" + str);
   Thread.sleep(2000);
   System.out.println("doG():: end:" + str);
  }
 }
 
 public void doH(String str) throws InterruptedException {
  synchronized (allLock) {
   System.out.println("doG():: start:" + str);
   Thread.sleep(2000);
   System.out.println("doG():: end:" + str);
  }
 }
}


 --------------------------------------------------------------------------------------------------------------------------------------

/**
 *
 * @author liangbing
 * @date Dec 26, 2008
 */
public class TestSync implements Runnable {
 
 private SyncObject ts = null;
 
 private String tag = null;
 
 public TestSync(SyncObject ts, String tag) {
  this.ts = ts;
  this.tag = tag;
 }

 public void run() {
  System.out.println("run.....");
  try {
   ts.doA(tag);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }
 
 public static void main(String[] args) {
  test1();
  //test2();
 }
 
 private static void test1() {
  SyncObject so = new SyncObject();
  TestSync a = new TestSync(so, "a");
  TestSync b = new TestSync(so, "b");
  Thread ta = new Thread(a);
  Thread tb = new Thread(b);
  ta.start();
  tb.start();
 }
 
 private static void test2() {
  SyncObject so1 = new SyncObject();
  SyncObject so2 = new SyncObject();
  TestSync a = new TestSync(so1, "a");
  TestSync b = new TestSync(so2, "b");
  Thread ta = new Thread(a);
  Thread tb = new Thread(b);
  ta.start();
  tb.start();
 }
}

--------------------------------------------------------------------------------------------------------------------------------------
/**
 *
 * @author liangbing
 * @date Dec 26, 2008
 */
public class TestSync1 implements Runnable {

 private SyncObject ts = null;
 
 private String tag = null;
 
 public TestSync1(SyncObject ts, String tag) {
  this.ts = ts;
  this.tag = tag;
 }

 public void run() {
  System.out.println("run.....");
  try {
   ts.doB(tag);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }
 
 public static void main(String[] args) {
  //test1();
  test2();
 }

 private static void test1() {
  SyncObject so = new SyncObject();
  TestSync a = new TestSync(so, "a");
  TestSync1 b = new TestSync1(so, "b");
  Thread ta = new Thread(a);
  Thread tb = new Thread(b);
  ta.start();
  tb.start();
 }
 
 private static void test2() {
  SyncObject so1 = new SyncObject();
  SyncObject so2 = new SyncObject();
  TestSync a = new TestSync(so1, "a");
  TestSync1 b = new TestSync1(so2, "b");
  Thread ta = new Thread(a);
  Thread tb = new Thread(b);
  ta.start();
  tb.start();
 }
}

--------------------------------------------------------------------------------------------------------------------------------------
/**
 *
 * @author liangbing
 * @date Dec 26, 2008
 */
public class TestSync2 implements Runnable {

 private SyncObject ts = null;
 
 private String tag = null;
 
 public TestSync2(SyncObject ts, String tag) {
  this.ts = ts;
  this.tag = tag;
 }

 public void run() {
  System.out.println("run.....");
  try {
   ts.doC(tag);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }
 
 public static void main(String[] args) {
  test1();
 }
 
 private static void test1() {
  SyncObject so = new SyncObject();
  TestSync a = new TestSync(so, "a");
  TestSync1 b = new TestSync1(so, "b");
  TestSync2 c = new TestSync2(so, "c");
  Thread ta = new Thread(a);
  Thread tb = new Thread(b);
  Thread tc = new Thread(c);
  ta.start();
  tb.start();
  tc.start();
 }
}

--------------------------------------------------------------------------------------------------------------------------------------
/**
 *
 * @author liangbing
 * @date Dec 29, 2008
 */
public class TestSync3 implements Runnable {

private SyncObject ts = null;
 
 private String tag = null;
 
 private Object lock = null;
 
 public TestSync3(SyncObject ts, String tag, Object lock) {
  this.ts = ts;
  this.tag = tag;
  this.lock = lock;
 }

 public void run() {
  System.out.println("run.....");
  try {
   ts.doD(tag, lock);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }
 
 public static void main(String[] args) {
  //test1();
  //test2();
  //test3();
  test4();
 }

 private static void test1() {
  SyncObject so = new SyncObject();
  String lock = "";
  TestSync3 a = new TestSync3(so, "a", lock);
  TestSync3 b = new TestSync3(so, "b", lock);
  Thread ta = new Thread(a);
  Thread tb = new Thread(b);
  ta.start();
  tb.start();
 }
 
 private static void test2() {
  SyncObject so = new SyncObject();
  String lock1 = "L1";
  String lock2 = "L2";
  TestSync3 a = new TestSync3(so, "a", lock1);
  TestSync3 b = new TestSync3(so, "b", lock2);
  Thread ta = new Thread(a);
  Thread tb = new Thread(b);
  ta.start();
  tb.start();
 }
 
 private static void test3() {
  SyncObject so = new SyncObject();
  String lock1 = "";
  String lock2 = "";
  TestSync3 a = new TestSync3(so, "a", lock1);
  TestSync3 b = new TestSync3(so, "b", lock2);
  Thread ta = new Thread(a);
  Thread tb = new Thread(b);
  ta.start();
  tb.start();
 }
 
 private static void test4() {
  SyncObject so = new SyncObject();
  String lock1 = "L1";
  String lock2 = "L1";
  TestSync3 a = new TestSync3(so, "a", lock1);
  TestSync3 b = new TestSync3(so, "b", lock2);
  Thread ta = new Thread(a);
  Thread tb = new Thread(b);
  ta.start();
  tb.start();
 }
}

--------------------------------------------------------------------------------------------------------------------------------------
/**
 *
 * @author liangbing
 * @date Dec 29, 2008
 */
public class TestSync4 implements Runnable {

 private SyncObject ts = null;
 
 private String tag = null;
 
 public TestSync4(SyncObject ts, String tag) {
  this.ts = ts;
  this.tag = tag;
 }

 public void run() {
  System.out.println("run.....");
  try {
   ts.doE(tag);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }
 
 public static void main(String[] args) {
  //test1();
  test2();
 }
 
 /**
  * 可以同步,同一个对象
  */
 private static void test1() {
  SyncObject so = new SyncObject();
  TestSync4 a = new TestSync4(so, "a");
  TestSync4 b = new TestSync4(so, "b");
  Thread ta = new Thread(a);
  Thread tb = new Thread(b);
  ta.start();
  tb.start();
 }
 
 /**
  * 不能同步,因为不是同一个对象
  */
 private static void test2() {
  SyncObject so1 = new SyncObject();
  SyncObject so2 = new SyncObject();
  TestSync4 a = new TestSync4(so1, "a");
  TestSync4 b = new TestSync4(so2, "b");
  Thread ta = new Thread(a);
  Thread tb = new Thread(b);
  ta.start();
  tb.start();
 }
}

--------------------------------------------------------------------------------------------------------------------------------------
/**
 *
 * @author liangbing
 * @date Dec 29, 2008
 */
public class TestSync5 implements Runnable {

 private String tag = null;
 
 public TestSync5(String tag) {
  this.tag = tag;
 }

 public void run() {
  System.out.println("run.....");
  try {
   SyncObject.doF(tag);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }
 
 public static void main(String[] args) {
  test1();
 }
 
 private static void test1() {
  TestSync5 a = new TestSync5("a");
  TestSync5 b = new TestSync5("b");
  Thread ta = new Thread(a);
  Thread tb = new Thread(b);
  ta.start();
  tb.start();
 }
}

--------------------------------------------------------------------------------------------------------------------------------------
/**
 *
 * @author liangbing
 * @date Dec 30, 2008
 */
public class TestSync6 implements Runnable {

 private SyncObject ts = null;
 
 private String tag = null;
 
 public TestSync6(SyncObject ts, String tag) {
  this.ts = ts;
  this.tag = tag;
 }

 public void run() {
  System.out.println("run.....");
  try {
   ts.doG(tag);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }
 
 public static void main(String[] args) {
  //test1();
  test2();
 }
 
 private static void test1() {
  SyncObject so = new SyncObject();
  TestSync6 a = new TestSync6(so, "a");
  TestSync6 b = new TestSync6(so, "b");
  Thread ta = new Thread(a);
  Thread tb = new Thread(b);
  ta.start();
  tb.start();
 }
 
 private static void test2() {
  SyncObject so1 = new SyncObject();
  SyncObject so2 = new SyncObject();
  TestSync6 a = new TestSync6(so1, "a");
  TestSync6 b = new TestSync6(so2, "b");
  Thread ta = new Thread(a);
  Thread tb = new Thread(b);
  ta.start();
  tb.start();
 }
}

--------------------------------------------------------------------------------------------------------------------------------------
/**
 *
 * @author liangbing
 * @date Dec 30, 2008
 */
public class TestSync7 implements Runnable {

 private SyncObject ts = null;
 
 private String tag = null;
 
 public TestSync7(SyncObject ts, String tag) {
  this.ts = ts;
  this.tag = tag;
 }

 public void run() {
  System.out.println("run.....");
  try {
   ts.doH(tag);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }
 
 public static void main(String[] args) {
  //test1();
  test2();
 }
 
 /**
  * 可以同步,static对象
  */
 private static void test1() {
  SyncObject so = new SyncObject();
  TestSync7 a = new TestSync7(so, "a");
  TestSync7 b = new TestSync7(so, "b");
  Thread ta = new Thread(a);
  Thread tb = new Thread(b);
  ta.start();
  tb.start();
 }
 
 /**
  * 可以同步,static对象
  */
 private static void test2() {
  SyncObject so1 = new SyncObject();
  SyncObject so2 = new SyncObject();
  TestSync7 a = new TestSync7(so1, "a");
  TestSync7 b = new TestSync7(so2, "b");
  Thread ta = new Thread(a);
  Thread tb = new Thread(b);
  ta.start();
  tb.start();
 }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值