synchronized的常見使用方式
修飾代碼塊(同步代碼塊)
synchronized (object) {
//具體代碼
}
修飾方法
synchronized void test(){
//具體代碼
}
synchronized不能繼承?(插曲)
父類A:
public class A {
synchronized void test() throws Exception {
try {
System.out.println("main 下一步 sleep begin threadName="
+ Thread.currentThread().getName() + " time="
+ System.currentTimeMillis());
Thread.sleep(5000);
System.out.println("main 下一步 sleep end threadName="
+ Thread.currentThread().getName() + " time="
+ System.currentTimeMillis());
} catch (Exception e) {
e.printStackTrace();
}
}
}
子類B:(未重寫test方法)
public class B extends A {
}
子類C:(重寫test方法)
public class C extends A {
@Override
void test() throws Exception{
try {
System.out.println("sub 下一步 sleep begin threadName="
+ Thread.currentThread().getName() + " time="
+ System.currentTimeMillis());
Thread.sleep(5000);
System.out.println("sub 下一步 sleep end threadName="
+ Thread.currentThread().getName() + " time="
+ System.currentTimeMillis());
} catch (Exception e) {
e.printStackTrace();
}
}
}
線程A:
public class ThreadA extends Thread {
private A a;
public void setter (A a) {
this.a = a;
}
@Override
public void run() {
try{
a.test();
}catch (Exception e){
}
}
}
線程B:
public class ThreadB extends Thread {
private B b;
public void setB(B b){
this.b=b;
}
@Override
public void run() {
try{
b.test();
}catch (Exception e){
}
}
}
線程C:
public class ThreadC extends Thread{
private C c;
public void setC(C c){
this.c=c;
}
@Override
public void run() {
try{
c.test();
}catch (Exception e){
}
}
}
測試類test:
public class test {
public static void main(String[] args) throws Exception {
A a = new A();
ThreadA A1 = new ThreadA();
A1.setter(a);
A1.setName("A1");
A1.start();
ThreadA A2 = new ThreadA();
A2.setter(a);
A2.setName("A2");
A2.start();
A1.join();
A2.join();
System.out.println("=============");
B b = new B();
ThreadB B1 = new ThreadB();
B1.setB(b);
B1.setName("B1");
B1.start();
ThreadB B2 = new ThreadB();
B2.setB(b);
B2.setName("B2");
B2.start();
B1.join();
B2.join();
System.out.println("=============");
C c = new C();
ThreadC C1 = new ThreadC();
C1.setName("C1");
C1.setC(c);
C1.start();
ThreadC C2 = new ThreadC();
C2.setName("C2");
C2.setC(c);
C2.start();
C1.join();
C2.join();
}
}
運行結果:
子類B繼承了父類A,但是沒有重寫test方法,ThreadB仍然是同步的。子類C繼承了父類A,也重寫了test方法,但是未明確寫上synchronized,所以這個方法並不是同步方法。只有顯式的寫上synchronized關鍵字,纔是同步方法。
所以synchronized不能繼承這句話有歧義,我們只要記住子類如果想要重寫父類的同步方法,synchronized關鍵字一定要顯示寫出,否則無效。
修飾靜態方法
synchronized static void test(){
//具體代碼
}
修飾類
synchronized (Example2.class) {
//具體代碼
}