国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > Java > 正文

java多線程編程之Synchronized關(guān)鍵字詳解

2019-11-26 14:20:52
字體:
供稿:網(wǎng)友

本文介紹JAVA多線程中的synchronized關(guān)鍵字作為對(duì)象鎖的一些知識(shí)點(diǎn)。

所謂對(duì)象鎖,就是就是synchronized 給某個(gè)對(duì)象 加鎖。關(guān)于 對(duì)象鎖 可參考:這篇文章

 一、分析

synchronized可以修飾實(shí)例方法,如下形式:

public class MyObject {  synchronized public void methodA() {    //do something....  }

這里,synchronized 關(guān)鍵字鎖住的是當(dāng)前對(duì)象。這也是稱為對(duì)象鎖的原因。

為啥鎖住當(dāng)前對(duì)象?因?yàn)?methodA()是個(gè)實(shí)例方法,要想執(zhí)行methodA(),需要以 對(duì)象.方法() 的形式進(jìn)行調(diào)用(obj.methodA(),obj是MyObject類的一個(gè)對(duì)象,synchronized就是把obj這個(gè)對(duì)象加鎖了)。

上面代碼也可寫成這樣:

public class MyObject {  public void methodA() {    synchronized(this){      //do something....    }  } 

二、特點(diǎn)

使用synchronized關(guān)鍵字同步一個(gè)明顯的特點(diǎn)是:MyObject類中定義有多個(gè)synchronized修飾的實(shí)例方法時(shí),若多個(gè)線程擁有同一個(gè)MyObject類的對(duì)象,則這些方法只能以同步的方式執(zhí)行。即,執(zhí)行完一個(gè)synchronized修飾的方法后,才能執(zhí)行另一個(gè)synchronized修飾的方法。

如下:

public class MyObject {  synchronized public void methodA() {    //do something....  }  synchronized public void methodB() {    //do some other thing  }}

MyObject類中有兩個(gè)synchronized修飾的方法。

public class ThreadA extends Thread {  private MyObject object;//省略構(gòu)造方法  @Override  public void run() {    super.run();    object.methodA();  }}

線程A執(zhí)行methodA()

public class ThreadB extends Thread {  private MyObject object;//省略構(gòu)造方法  @Override  public void run() {    super.run();    object.methodB();  }}

線程B執(zhí)行methodB()

public class Run {  public static void main(String[] args) {    MyObject object = new MyObject();    //線程A與線程B 持有的是同一個(gè)對(duì)象:object    ThreadA a = new ThreadA(object);    ThreadB b = new ThreadB(object);    a.start();    b.start();  }}

由于線程A和線程B持有同一個(gè)MyObject類的對(duì)象object,盡管這兩個(gè)線程需要調(diào)用不同的方法,但是必須是同步的,比如:線程B需要等待線程A執(zhí)行完了methodA()方法之后,它才能執(zhí)行methodB()方法。

 三、結(jié)論

從上可以看出,本文中講述的 synchronized 鎖的范圍是整個(gè)對(duì)象。如果一個(gè)類中有多個(gè)synchronized修飾的同步方法,且多個(gè)線程持有該類的同一個(gè)對(duì)象(該類的相同的對(duì)象),盡管它們調(diào)用不同的方法,各個(gè)方法的執(zhí)行也是同步的。

如果各個(gè)同步的方法之間沒有共享變量,或者說各個(gè)方法之間沒有聯(lián)系,但也只能同步執(zhí)行,這會(huì)影響效率。

四、應(yīng)用--使用synchronized避免 因數(shù)據(jù)不一致性而導(dǎo)致讀臟數(shù)據(jù)的情況

如下示例:

public class MyObject {  private String userName = "b";  private String passWord = "bb";    synchronized public void methodA(String userName, String passWord) {    this.userName = userName;    try{      Thread.sleep(5000);    }catch(InterruptedException e){          }    this.passWord = passWord;  }  synchronized public void methodB() {    System.out.println("userName" + userName + ": " + "passWord" + passWord);  }}

methodA()負(fù)責(zé)更改用戶名和密碼。在現(xiàn)實(shí)中,一個(gè)用戶名對(duì)應(yīng)著一個(gè)密碼。

methodB()負(fù)責(zé)讀取用戶名和密碼。

如果methodB()沒有用synchronized 修飾,線程A在調(diào)用methodA()執(zhí)行到第7行,更改了用戶名,因某種原因(比如在第9行睡眠了)放棄了CPU。

此時(shí),如果線程B去執(zhí)行methodB(),那么讀取到的用戶名是線程A更改了的用戶名("a"),但是密碼卻是原來的密碼("bb")。因?yàn)椋€程A睡眠了,還沒有來得及更改密碼。

但是,如果methodB()用synchronized修飾,那么線程B只能等待線程A執(zhí)行完畢之后(即改了用戶名,也改了密碼),才能執(zhí)行methodB讀取用戶名和密碼。因此,就避免了數(shù)據(jù)的不一致性而導(dǎo)致的臟讀問題。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家學(xué)習(xí)java程序設(shè)計(jì)有所幫助。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 云霄县| 牡丹江市| 海口市| 当阳市| 中卫市| 壶关县| 潢川县| 宁德市| 武隆县| 子长县| 霍州市| 石景山区| 北辰区| 宝坻区| 名山县| 青州市| 绥芬河市| 彭阳县| 泗水县| 博兴县| 深州市| 河间市| 崇左市| 天全县| 蕲春县| 井研县| 洛川县| 揭阳市| 常宁市| 萍乡市| 密山市| 怀安县| 阿图什市| 鄯善县| 宜章县| 中西区| 饶阳县| 靖州| 中西区| 大洼县| 上高县|