關(guān)鍵字 synchronized 的作用是實(shí)現(xiàn)線程間的同步衩椒。它的工作是對同步的代碼加鎖凹耙,使得每一次嗦篱,只有一個(gè)線程進(jìn)入同步塊填物,從而保證線程間的安全性纹腌。
synchronized 可以有多種用法,下面是常用的三種方式滞磺。
- 指定加鎖對象:對給定對象加鎖升薯,進(jìn)入同步代碼前要活的給定對象的鎖。
- 直接作用于實(shí)例方法:相當(dāng)于對當(dāng)前實(shí)例加鎖击困,進(jìn)入同步代碼前要獲得當(dāng)前實(shí)例的鎖涎劈。
- 直接作用于靜態(tài)方法:相當(dāng)于對當(dāng)前類加鎖,進(jìn)入同步代碼前要獲得當(dāng)前類的鎖。
例子1(對象加鎖):
/**
* Created by zhangjianghong on 2017/8/1.
*/
public class SynClass implements Runnable{
static int i = 0;
static SynClass synClass = new SynClass();
@Override
public void run() {
for (int j = 0; j < 10000; j++) {
// synchronized (synClass){
i++;
// }
}
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(synClass);
Thread t2 = new Thread(synClass);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(i);
}
}
注意 责语,我們在代碼中注釋的代碼內(nèi)容炮障,此時(shí)的運(yùn)行結(jié)果總是小于20000的,因?yàn)閮蓚€(gè)線程每次對于 i 自增時(shí)坤候,取到的值都不是最新的值胁赢,線程產(chǎn)生了混亂(即使用volatile也無效,因?yàn)関olatile無法保證符合操作的原子性)白筹。當(dāng)釋放注釋以后智末,每次得到的值就會(huì)是20000。
當(dāng)然 我們可以將以上代碼修改如下(方法加鎖徒河,省略 main 方法) 也會(huì)得到正確的結(jié)果:
public class SynClass implements Runnable{
static volatile int i = 0;
static SynClass synClass = new SynClass();
public synchronized void add (){
for (int j = 0; j < 10000; j++) {
i ++;
}
}
@Override
public void run() {
add();
}
}
類鎖(省略 main 方法):
@Override
public void run() {
for (int j = 0; j < 10000; j++) {
synchronized (SynClass.class){
i++;
}
}
}