概述
在近期一个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();
}
}
最后
以上就是兴奋香水为你收集整理的互斥锁-同步的全部内容,希望文章能够帮你解决互斥锁-同步所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复