Java中獲取鎖有兩種方式哈打,一種是使用synchronized關(guān)鍵字迂苛,另外一種就是使用Lock接口的實(shí)現(xiàn)類直颅。 本文重點(diǎn)講 synchronized
synchronized是Java中的關(guān)鍵字刮便,是一種同步鎖褪秀。它修飾的對(duì)象有以下幾種:
1. 修飾一個(gè)代碼塊蓄诽,被修飾的代碼塊稱為同步語(yǔ)句塊,其作用的范圍是大括號(hào){}括起來(lái)的代碼媒吗,作用的對(duì)象是調(diào)用這個(gè)代碼塊的對(duì)象仑氛;?
2. 修飾一個(gè)方法,被修飾的方法稱為同步方法闸英,其作用的范圍是整個(gè)方法锯岖,作用的對(duì)象是調(diào)用這個(gè)方法的象;?
3. 修改一個(gè)靜態(tài)的方法甫何,其作用的范圍是整個(gè)靜態(tài)方法出吹,作用的對(duì)象是這個(gè)類的所有對(duì)象;?
4. 修改一個(gè)類辙喂,其作用的范圍是synchronized后面括號(hào)括起來(lái)的部分捶牢,作用主的對(duì)象是這個(gè)類的所有對(duì)象。?
5. 類鎖和對(duì)象鎖是兩個(gè)不一樣的鎖巍耗,控制著不同的區(qū)域秋麸,它們是互不干擾的。同樣炬太,線程獲得對(duì)象鎖的同時(shí)灸蟆,也可以獲得該類鎖,即同時(shí)獲得兩個(gè)鎖亲族。
就是說(shuō)炒考,不同線程可以同時(shí)訪問(wèn)加了對(duì)象鎖和類鎖的方法
public class SynchronizedTest {
? ? /**
? ? *? synchronized (this) 鎖住代碼塊,鎖的是當(dāng)前對(duì)象
? ? */
? ? public void test1() {
? ? ? ? synchronized (this) {
? ? ? ? ? ? int i = 5;
? ? ? ? ? ? while (i-- > 0) {
? ? ? ? ? ? ? ? System.out.println(Thread.currentThread().getName() + " : " + i);
? ? ? ? ? ? ? ? sleepFuc(500);
}
}
}
? ? /**
? ? * synchronized加在成員方法上鎖的是當(dāng)前對(duì)象孽水,等價(jià)于 synchronized (this)
*/
? ? public synchronized void test2() {
? ? ? ? int i = 5;
? ? ? ? while (i-- > 0) {
? ? ? ? ? ? System.out.println(Thread.currentThread().getName() + " : " + i);
? ? ? ? ? ? sleepFuc(500);
}
}
? ? /**
? ? * 非同步方法
? ? */
? ? public? void test3() {
? ? ? ? int i = 5;
? ? ? ? while (i-- > 0) {
? ? ? ? ? ? System.out.println(Thread.currentThread().getName() + " : " + i);
? ? ? ? ? ? ? ? sleepFuc(500);
}
}
? ? /**
? ? * synchronized用在靜態(tài)方法上是類鎖方法等價(jià)于 synchronized (SynchronizedTest.class)
*/
? ? public static synchronized void test4() {
? ? ? ? int i = 5;
? ? ? ? while (i-- > 0) {
? ? ? ? ? ? System.out.println(Thread.currentThread().getName() + " : " + i);
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? Thread.sleep(500);
? ? ? ? ? ? } catch (InterruptedException ie) {
}
}
}
? ? /**
? ? * 類鎖方法
? ? */
? ? public void test5() {
? ? ? ? synchronized (SynchronizedTest.class) {
? ? ? ? ? ? int i = 5;
? ? ? ? ? ? while (i-- > 0) {
? ? ? ? ? ? ? ? System.out.println(Thread.currentThread().getName() + " : " + i);
? ? ? ? ? ? ? ? sleepFuc(500);
}
}
}
? ? private void sleepFuc(int mill) {
? ? ? ? try {
? ? ? ? ? ? Thread.sleep(mill);
? ? ? ? } catch (InterruptedException ie) {
}
}
? ? public static void main(String[] args) {
? ? ? ? final SynchronizedTest test = new SynchronizedTest();
//? ? ? ? Thread test1 = new Thread(test::test1, "synchronized (this)");
? ? ? ? Thread test2 = new Thread(test::test2, "synchronized method");
//? ? ? ? Thread test3 = new Thread(test::test3, "not synchronized");
? ? ? ? Thread test4 = new Thread(SynchronizedTest::test4, "static synchronized method");
//? ? ? ? Thread test5 = new Thread(test::test5, " synchronized (SynchronizedTest.class)");
//? ? ? ? test1.start();
? ? ? ? test2.start();
//? ? ? ? test3.start();
? ? ? ? test4.start();
//? ? ? ? test5.start();
? ? }
? ? /*
? ? *? 非靜態(tài)方法:
? ? *? 給對(duì)象加鎖(可以理解為給這個(gè)對(duì)象的內(nèi)存上鎖,注意 只是這塊內(nèi)存,其他同類對(duì)象都會(huì)有各自的內(nèi)存鎖),這時(shí)-? ? ? ?*?候 在其他一個(gè)以上線程中執(zhí)行該對(duì)象的這個(gè)同步方法(注意:是該對(duì)象)就會(huì)產(chǎn)生互斥??
? ? *? 靜態(tài)方法:
? ? * 相當(dāng)于在類上加鎖(*.class 位于代碼區(qū),靜態(tài)方法位于靜態(tài)區(qū)域,這個(gè)類產(chǎn)生的對(duì)象公用這個(gè)靜態(tài)方法,所以這塊? ? ? * 內(nèi)存票腰,N個(gè)對(duì)象來(lái)競(jìng)爭(zhēng)), 這時(shí)候,只要是這個(gè)類產(chǎn)生的對(duì)象,在調(diào)用這個(gè)靜態(tài)方法時(shí)都會(huì)產(chǎn)生互斥
*/
}