1.synchronized与static synchronized 的区别
synchronized是对类的当前实例进行加锁,防止其他线程同时访问该类的该实例的所有synchronized块,注意这里是“类的当前实例”, 类的两个不同实例就没有这种约束了。那么static synchronized恰好就是要控制类的所有实例的访问了,static synchronized是限制线程同时访问jvm中该类的所有实例同时访问对应的代码快。实际上,在类中某方法或某代码块中有 synchronized,那么在生成一个该类实例后,改类也就有一个监视快,放置线程并发访问改实例synchronized保护快,而static synchronized则是所有该类的实例公用一个监视快了,也也就是两个的区别了,也就是synchronized相当于 this.synchronized,而static synchronized相当于Something.synchronized.
一个日本作者-结成浩的《java多线程设计模式》有这样的一个列子:
pulbic class Something(){
public synchronized void isSyncA(){}
public synchronized void isSyncB(){}
public static synchronized void cSyncA(){}
public static synchronized void cSyncB(){}
}
那么,加入有Something类的两个实例a与b,那么下列组方法何以被1个以上线程同时访问呢
a. x.isSyncA()与x.isSyncB()
b. x.isSyncA()与y.isSyncA()
c. x.cSyncA()与y.cSyncB()
d. x.isSyncA()与Something.cSyncA()
这里,很清楚的可以判断:
a,都是对同一个实例的synchronized域访问,因此不能被同时访问
b,是针对不同实例的,因此可以同时被访问
c,因为是static synchronized,所以不同实例之间仍然会被限制,相当于Something.isSyncA()与 Something.isSyncB()了,因此不能被同时访问。
那么,第d呢?,书上的 答案是可以被同时访问的,答案理由是synchronzied的是实例方法与synchronzied的类方法由于锁定(lock)不同的原因。
个人分析也就是synchronized 与static synchronized 相当于两帮派,各自管各自,相互之间就无约束了,可以被同时访问。目前还不是分清楚java内部设计synchronzied是怎么样实现的。
结论:A: synchronized static是某个类的范围,synchronized static cSync{}防止多个线程同时访问这个 类中的synchronized static 方法。它可以对类的所有对象实例起作用。
B: synchronized 是某实例的范围,synchronized isSync(){}防止多个线程同时访问这个实例中的synchronized 方法。
2.synchronized方法与synchronized代码快的区别
synchronized methods(){} 与synchronized(this){}之间没有什么区别,只是 synchronized methods(){} 便于阅读理解,而synchronized(this){}可以更精确的控制冲突限制访问区域,有时候表现更高效率。
3.synchronized关键字是不能继承的
这个在http://www.learndiary.com/archives/diaries/2910.htm一文中看到的,我想这一点也是很值得注意的,继承时子类的覆盖方法必须显示定义成synchronize
范例:
package com.rr.current2.c2_2_synchronized.teststatic;
/**
* Created by isaac_gu on 2016/5/24.
*/
public class Test {
public static void main(String[] args) {
Test t = new Test();
t.test1();
t.test2();
t.test3();
t.test4();
t.test5();
t.test6();
}
/**
* a. x.isSyncA()与x.isSyncB()
* 运行结果:
* A 正在执行 isSyncA!
* A 完成 isSyncA 的操作!
* B 正在执行 isSyncB!
* B 完成 isSyncB 的操作!
* 结论: 不能被多个线程同时访问
*/
public void test1() {
System.out.println("************************** 1. x.isSyncA()与x.isSyncB() ***************************");
final Something x = new Something();
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
x.isSyncA("A");
}
});
Thread threadB = new Thread(new Runnable() {
@Override
public void run() {
x.isSyncB("B");
}
});
threadA.start();
threadB.start();
try {
threadA.join();
threadB.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* x.isSyncA()与y.isSyncA() - 可以同时访问
*/
public void test2() {
System.out.println("************************** 2. x.isSyncA()与y.isSyncA() ***************************");
final Something x = new Something();
final Something y = new Something();
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
x.isSyncA("A");
}
});
Thread threadB = new Thread(new Runnable() {
@Override
public void run() {
y.isSyncA("B");
}
});
threadA.start();
threadB.start();
try {
threadA.join();
threadB.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* x.cSyncA()与y.cSyncB() - 不可以同时访问
*/
public void test3() {
System.out.println("************************** 3. x.cSyncA()与y.cSyncB() ***************************");
final Something x = new Something();
final Something y = new Something();
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
x.cSyncA("A");
}
});
Thread threadB = new Thread(new Runnable() {
@Override
public void run() {
y.cSyncB("B");
}
});
threadA.start();
threadB.start();
try {
threadA.join();
threadB.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* x.isSyncA()与Something.cSyncA() - 可以同时访问
*/
public void test4() {
System.out.println("************************** 4. x.isSyncA()与Something.cSyncA() ***************************");
final Something x = new Something();
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
x.isSyncA("A");
}
});
Thread threadB = new Thread(new Runnable() {
@Override
public void run() {
Something.cSyncA("B");
}
});
threadA.start();
threadB.start();
try {
threadA.join();
threadB.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* x.isSyncA()与 x.normalMtd() - 可以同时访问
*/
public void test5() {
System.out.println("************************** 5. x.isSyncA()与 x.normalMtd() ***************************");
final Something x = new Something();
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
x.isSyncA("A");
}
});
Thread threadB = new Thread(new Runnable() {
@Override
public void run() {
x.normalMtd("B");
}
});
threadA.start();
threadB.start();
try {
threadA.join();
threadB.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* x.isSyncA()与 Something.staticMtdA() - 可以同时访问
*/
public void test6() {
System.out.println("************************** 6. x.isSyncA()与 Something.staticMtdA() ***************************");
final Something x = new Something();
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
x.isSyncA("A");
}
});
Thread threadB = new Thread(new Runnable() {
@Override
public void run() {
Something.staticMtdA("B");
}
});
threadA.start();
threadB.start();
try {
threadA.join();
threadB.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Something
package com.rr.current2.c2_2_synchronized.teststatic;
import java.util.concurrent.TimeUnit;
/**
* Created by isaac_gu on 2016/5/24.
*/
public class Something {
public synchronized void isSyncA(String name) {
System.out.printf("%s 正在执行 isSyncA!\n", name);
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("%s 完成 isSyncA 的操作!\n", name);
}
public synchronized void isSyncB(String name) {
System.out.printf("%s 正在执行 isSyncB!\n", name);
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("%s 完成 isSyncB 的操作!\n", name);
}
public static synchronized void cSyncA(String name) {
System.out.printf("%s 正在执行 cSyncA!\n", name);
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("%s 完成 cSyncA 的操作!\n", name);
}
public static synchronized void cSyncB(String name) {
System.out.printf("%s 正在执行 cSyncB!\n", name);
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("%s 完成 cSyncB 的操作!\n", name);
}
public void normalMtd(String name) {
System.out.printf("%s 正在执行 normalA!\n", name);
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("%s 完成 normalA 的操作!\n", name);
}
public static void staticMtdA(String name) {
System.out.printf("%s 正在执行 normalA!\n", name);
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("%s 完成 normalA 的操作!\n", name);
}
}
结果:
************************** 1. x.isSyncA()与x.isSyncB() ***************************
B 正在执行 isSyncB!
B 完成 isSyncB 的操作!
A 正在执行 isSyncA!
A 完成 isSyncA 的操作!
************************** 2. x.isSyncA()与y.isSyncA() ***************************
A 正在执行 isSyncA!
B 正在执行 isSyncA!
A 完成 isSyncA 的操作!
B 完成 isSyncA 的操作!
************************** 3. x.cSyncA()与y.cSyncB() ***************************
A 正在执行 cSyncA!
A 完成 cSyncA 的操作!
B 正在执行 cSyncB!
B 完成 cSyncB 的操作!
************************** 4. x.isSyncA()与Something.cSyncA() ***************************
A 正在执行 isSyncA!
B 正在执行 cSyncA!
A 完成 isSyncA 的操作!
B 完成 cSyncA 的操作!
************************** 5. x.isSyncA()与 x.normalMtd() ***************************
A 正在执行 isSyncA!
B 正在执行 normalA!
B 完成 normalA 的操作!
A 完成 isSyncA 的操作!
************************** 6. x.isSyncA()与 Something.staticMtdA() ***************************
A 正在执行 isSyncA!
B 正在执行 normalA!
B 完成 normalA 的操作!
A 完成 isSyncA 的操作!
synchronized块:
/**
* x.bSyncA()与 x.bSyncA() - 可以同时访问
* synchronize方法、synchronized块与static synchronized方法可以同时访问
*/
public void test7() {
System.out.println("************************** 7. x.bSyncA()与 x.bSyncA() ***************************");
final Something x = new Something();
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
x.bSyncA("A");
}
});
Thread threadB = new Thread(new Runnable() {
@Override
public void run() {
x.bSyncB("B");
}
});
Thread threadC = new Thread(new Runnable() {
@Override
public void run() {
x.isSyncA("C");
}
});
Thread threadD = new Thread(new Runnable() {
@Override
public void run() {
Something.cSyncA("D");
}
});
Thread threadE = new Thread(new Runnable() {
@Override
public void run() {
x.isSyncA("E");
}
});
threadA.start();
threadB.start();
threadC.start();
threadD.start();
threadE.start();
try {
threadA.join();
threadB.join();
threadC.join();
threadD.join();
threadE.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
结果:
A 正在执行 bSyncA!
D 正在执行 cSyncA!
B 正在执行 bSyncB!
C 正在执行 isSyncA!
A 完成 bSyncA 的操作!
C 完成 isSyncA 的操作!
B 完成 bSyncB 的操作!
D 完成 cSyncA 的操作!
E 正在执行 isSyncA!
E 完成 isSyncA 的操作!