總結一下synchronized的用法:
1、修飾靜態方法
2、修飾實例方法
3、修飾代碼塊
一、首先看一下修飾靜態方法和修飾實例方法的區別,直接上代碼:
/*
* synchronized:修飾實例方法/修飾靜態方法
*/
public class SynchronizedTest2 {
public static void main(String[] args)
throws Exception {
AccountingSyncClass accountingSyncClass = new AccountingSyncClass();
Thread t1 = new Thread(new AccountingSyncClass());
Thread t2 = new Thread(new AccountingSyncClass());
t1.start();
t2.start();
t2.join();
t1.join();
System.out.println(accountingSyncClass.i);
}
public void getName2() {
System.out.println(SynchronizedTest2.class.getName());
}
}
class AccountingSyncClass implements Runnable {
static int i = 0;
static boolean flag = true;
// 作用於靜態方法,鎖是當前class對象,也就是AccountingSyncClass類對應的class對象
public static synchronized void increase() {
i++;
}
// 非靜態方法,鎖定當前實例對象
public synchronized void increase2() {
i++;
}
@Override
public void run() {
for (int j = 0; j < 1000000; j++) {
// increase();
increase2();
}
}
}
1、當run()方法中調用increase2(),main方法中兩個線程如果訪問的是同一個AccountingSyncClass的實例對象,則答應結果爲2000000,如果是兩個不同的實例對象,則結果不是2000000;
2、當run()方法中調用的是increase() [synchronized修飾的靜態方法],main方法啓動的線程無論訪問的是否是同一個AccountingSyncClass的實例對象,結果都是2000000;
3、如果一個線程A調用一個實例對象的非static synchronized方法,而線程B需要調用這個實例對象所屬類的靜態 synchronized方法,是允許的,不會發生互斥現象,因爲訪問static synchronized 方法佔用的鎖是當前類的class對象,而訪問非靜態 synchronized 方法佔用的鎖是當前實例對象鎖;
二、下面看一下synchronized如何修飾代碼塊,優勢:比修飾整個方法更加靈活!
public class SychronizedTest {
public static boolean flag = true;
public static StringBuffer s1 = new StringBuffer("123");
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
public void run() {
while (flag) {
synchronized (s1) {
try {
s1.wait();
System.out.println("t1 awake!");
flag = false;
} catch (InterruptedException e) {
}
}
}
}
}, "t1");
Thread t2 = new Thread(new Runnable() {
public void run() {
synchronized (s1) {
System.out.println(s1);
s1.notify();
}
}
}, "t2");
t1.start();
t2.start();
}
}
1、flag:用來終止線程;
2、線程t1和t2啓動,t1先拿到了s1的鎖,調用s1.wait()方法,釋放對s1的鎖;
3、線程t2獲得s1的鎖,執行方法塊,執行完成調用notify(),叫醒等待在s1對象上的其他線程(t1線程),並釋放s1的鎖。t2拿到s1的鎖繼續執行。
推薦博客:https://blog.csdn.net/javazejian/article/details/72828483,這篇博客講的非常好!