導航:首頁 > 編程語言 > java同步塊

java同步塊

發布時間:2022-03-12 11:30:19

java同步方法和同步代碼塊的區別

在Java語言中,每一個對象有一把鎖。線程可以使用synchronized關鍵字來獲取對象上的鎖。synchronized關鍵字可應用在方法級別(粗粒度鎖)或者是代碼塊級別(細粒度鎖)。
問題的由來:
看到這樣一個面試題:
//下列兩個方法有什麼區別public synchronized void method1(){} public void method2(){ synchronized (obj){}}

synchronized用於解決同步問題,當有多條線程同時訪問共享數據時,如果進行同步,就會發生錯誤,Java提供的解決方案是:只要將操作共享數據的語句在某一時段讓一個線程執行完,在執行過程中,其他線程不能進來執行可以。解決這個問題。這里在用synchronized時會有兩種方式,一種是上面的同步方法,即用synchronized來修飾方法,另一種是提供的同步代碼塊。
這里總感覺怪怪的,這兩種方法有什麼區別呢,基礎學得不好,於是就動手做了個簡單的測試,代碼如下:
public class SynObj { public synchronized void methodA() { System.out.println("methodA....."); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } } public void methodB() { synchronized(this) { System.out.pritntln("methodB....."); } } public void methodC() { String str = "sss"; synchronized (str) { System.out.println( "methodC....."); } }}
public class TestSyn { public static void main(String[] args) { final SynObj obj = new SynObj(); Thread t1 = new Thread(new Runnable() { @Override public void run() { obj.methodA(); } }); t1.start(); Thread t2 = new Thread(new Runnable() { @Override public void run() { obj.methodB(); } }); t2.start(); Thread t3 = new Thread(new Runnable() { @Override public void run() { obj.methodC(); } }); t3.start(); }}

這段小代碼片段列印結果如下:
methodA.....methodC.....//methodB會隔一段時間才會列印出來methodB.....

這段代碼的列印結果是,methodA…..methodC…..會很快列印出來,methodB…..會隔一段時間才列印出來,那麼methodB為什麼不能像methodC那樣很快被調用呢?
在啟動線程1調用方法A後,接著會讓線程1休眠5秒鍾,這時會調用方法C,注意到方法C這里用synchronized進行加鎖,這里鎖的對象是str這個字元串對象。但是方法B則不同,是用當前對象this進行加鎖,注意到方法A直接在方法上加synchronized,這個加鎖的對象是什麼呢?顯然,這兩個方法用的是一把鎖。
*由這樣的結果,我們就知道這樣同步方法是用什麼加鎖的了,由於線程1在休眠,這時鎖還沒釋放,導致線程2隻有在5秒之後才能調用方法B,由此,可知兩種加鎖機制用的是同一個鎖對象,即當前對象。

另外,同步方法直接在方法上加synchronized實現加鎖,同步代碼塊則在方法內部加鎖,很明顯,同步方法鎖的范圍比較大,而同步代碼塊范圍要小點,一般同步的范圍越大,性能就越差,一般需要加鎖進行同步的時候,肯定是范圍越小越好,這樣性能更好*。

⑵ java同步代碼塊

大括弧就是房子,小括弧里的對象就是鎖,就好比你加了一把鎖在房子上,一次只能有一個人拿到鑰匙進入到房子里,這就實現了同步。鎖對象可以是任意對象,加鎖是加在代碼上。this表示鎖對象用的是當前類的對象,Object表示基類,其實就是隨便創建了一個對象拿來當鎖用。

⑶ Java多線程同步同步代碼塊

票數弄多一些,休眠時間長一點,效果會好一些。

⑷ java里同步是什麼意思

一般有兩種方法 同步方法和同步代碼塊

假設P1、P2是同一個類的不同對象,這個類中定義了以下幾種情況的同步塊或同步方法,P1、P2就都可以調用它們。

1. 把synchronized當作函數修飾符時,示例代碼如下:

Public synchronized void methodAAA()

{

//….

}

這也就是同步方法,那這時synchronized鎖定的是哪個對象呢?它鎖定的是調用這個同步方法對象。也就是說,當一個對象P1在不同的線程中執行這個同步方法時,它們之間會形成互斥,達到同步的效果。但是這個對象所屬的Class所產生的另一對象P2卻可以任意調用這個被加了synchronized關鍵字的方法。

上邊的示例代碼等同於如下代碼:

public void methodAAA()

{

synchronized (this) // (1)

{

//…..

}

}

(1)處的this指的是什麼呢?它指的就是調用這個方法的對象,如P1。可見同步方法實質是將synchronized作用於object reference。――那個拿到了P1對象鎖的線程,才可以調用P1的同步方法,而對P2而言,P1這個鎖與它毫不相干,程序也可能在這種情形下擺脫同步機制的控制,造成數據混亂:(

2.同步塊,示例代碼如下:

public void method3(SomeObject so)

{

synchronized(so)

{

//…..

}

}

這時,鎖就是so這個對象,誰拿到這個鎖誰就可以運行它所控制的那段代碼。當有一個明確的對象作為鎖時,就可以這樣寫程序,但當沒有明確的對象作為鎖,只是想讓一段代碼同步時,可以創建一個特殊的instance變數(它得是一個對象)來充當鎖:

class Foo implements Runnable

{

private byte[] lock = new byte[0]; // 特殊的instance變數

Public void methodA()

{

synchronized(lock) { //… }

}

//…..

}

註:零長度的byte數組對象創建起來將比任何對象都經濟――查看編譯後的位元組碼:生成零長度的byte[]對象只需3條操作碼,而Object lock = new Object()則需要7行操作碼。

3.將synchronized作用於static 函數,示例代碼如下:

Class Foo

{

public synchronized static void methodAAA() // 同步的static 函數

{

//….

}

public void methodBBB()

{

synchronized(Foo.class) // class literal(類名稱字面常量)

}

}

代碼中的methodBBB()方法是把class literal作為鎖的情況,它和同步的static函數產生的效果是一樣的,取得的鎖很特別,是當前調用這個方法的對象所屬的類(Class,而不再是由這個Class產生的某個具體對象了)。

記得在《Effective Java》一書中看到過將 Foo.class和 P1.getClass()用於作同步鎖還不一樣,不能用P1.getClass()來達到鎖這個Class的目的。P1指的是由Foo類產生的對象。

可以推斷:如果一個類中定義了一個synchronized的static函數A,也定義了一個synchronized 的instance函數B,那麼這個類的同一對象Obj在多線程中分別訪問A和B兩個方法時,不會構成同步,因為它們的鎖都不一樣。A方法的鎖是Obj這個對象,而B的鎖是Obj所屬的那個Class。

⑸ java中同步有幾種方式啊

1。同步代碼塊:
synchronized(同一個數據){} 同一個數據:就是N條線程同時訪問一個數據。
2。
同步方法:
public synchronized 數據返回類型 方法名(){}

是使用 synchronized 來修飾某個方法,則該方法稱為同步方法。對於同步方法而言,無需顯示指定同步監視器,同步方法的同步監視器是
this
也就是該對象的本身(這里指的對象本身有點含糊,其實就是調用該同步方法的對象)通過使用同步方法,可非常方便的將某類變成線程安全的類,具有如下特徵:
1,該類的對象可以被多個線程安全的訪問。
2,每個線程調用該對象的任意方法之後,都將得到正確的結果。
3,每個線程調用該對象的任意方法之後,該對象狀態依然保持合理狀態。
註:synchronized關鍵字可以修飾方法,也可以修飾代碼塊,但不能修飾構造器,屬性等。
實現同步機制注意以下幾點: 安全性高,性能低,在多線程用。性能高,安全性低,在單線程用。
1,不要對線程安全類的所有方法都進行同步,只對那些會改變共享資源方法的進行同步。
2,如果可變類有兩種運行環境,當線程環境和多線程環境則應該為該可變類提供兩種版本:線程安全版本和線程不安全版本(沒有同步方法和同步塊)。在單線程中環境中,使用線程不安全版本以保證性能,在多線程中使用線程安全版本.

線程通訊:
為什麼要使用線程通訊?

使用synchronized
來修飾某個共享資源時(分同步代碼塊和同步方法兩種情況),當某個線程獲得共享資源的鎖後就可以執行相應的代碼段,直到該線程運行完該代碼段後才釋放對該

共享資源的鎖,讓其他線程有機會執行對該共享資源的修改。當某個線程佔有某個共享資源的鎖時,如果另外一個線程也想獲得這把鎖運行就需要使用wait()
和notify()/notifyAll()方法來進行線程通訊了。
Java.lang.object 里的三個方法wait() notify() notifyAll()
wait方法導致當前線程等待,直到其他線程調用同步監視器的notify方法或notifyAll方法來喚醒該線程。
wait(mills)方法
都是等待指定時間後自動蘇醒,調用wait方法的當前線程會釋放該同步監視器的鎖定,可以不用notify或notifyAll方法把它喚醒。
notify()
喚醒在同步監視器上等待的單個線程,如果所有線程都在同步監視器上等待,則會選擇喚醒其中一個線程,選擇是任意性的,只有當前線程放棄對該同步監視器的鎖定後,也就是使用wait方法後,才可以執行被喚醒的線程。
notifyAll()方法
喚醒在同步監視器上等待的所有的線程。只用當前線程放棄對該同步監視器的鎖定後,才可以執行被喚醒的線程

⑹ Java中線程同步的synchronized()(同步方法塊)這個括弧里的參數是啥

synchronized()、synchronized(this)、synchronized(類名.class)
synchronized加在非靜態方法前和synchronized(this)都是鎖住了這個類的對象,如果多線程訪問,對象不同,就鎖不住,對象固定是一個,就可鎖住。
synchronized(類名.class)和加在靜態方法前,是鎖住了代碼塊,不管多線程訪問的時候對象是不是同一個,能縮小代碼段的范圍就盡量縮小,能在代碼段上加同步就不要再整個方法上加同步,縮小鎖的粒度。

⑺ java 方法同步

設置三個同步變數不就完了,然後synchronized的時候就同步這三個變數區分就行了

⑻ Java同步方法和同步塊,哪個是更好的選擇

同步塊是更好的選擇,因為它不會鎖住整個對象(當然也可以讓它鎖住整個對象)。同步方法會鎖住整個對象,哪怕這個類中有多個不相關聯的同步塊,這通常會導致他們停止執行並需要等待獲得這個對象上的鎖。

⑼ java 同步塊內異常處理

想來應該會,不過你最好還是自己寫個程序測試下

⑽ Java中同步方法和同步代碼塊的區別是什麼

在Java語言中,每一個對象有一把鎖。線程可以使用synchronized關鍵字來獲取對象上的鎖。synchronized關鍵字可應用在方法級別(粗粒度鎖)或者是代碼塊級別(細粒度鎖)。

閱讀全文

與java同步塊相關的資料

熱點內容
優信二手車解壓後過戶 瀏覽:62
Windows常用c編譯器 瀏覽:778
關於改善國家網路安全的行政命令 瀏覽:833
安卓如何下載網易荒野pc服 瀏覽:654
javainetaddress 瀏覽:104
蘋果4s固件下載完了怎麼解壓 瀏覽:1003
命令zpa 瀏覽:285
python編譯器小程序 瀏覽:944
在app上看視頻怎麼光線調暗 瀏覽:540
可以中文解壓的解壓軟體 瀏覽:593
安卓卸載組件應用怎麼安裝 瀏覽:913
使用面向對象編程的方式 瀏覽:339
程序員項目經理的年終總結範文 瀏覽:929
內衣的加密設計用來幹嘛的 瀏覽:432
淮安數據加密 瀏覽:292
魔高一丈指標源碼 瀏覽:982
松下php研究所 瀏覽:168
c回調java 瀏覽:400
夢幻端游長安地圖互通源碼 瀏覽:746
電腦本地文件如何上傳伺服器 瀏覽:313