日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java synchronized 详解

發布時間:2025/3/21 java 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java synchronized 详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

下面的文字均來自其它博客和網頁。

參考:http://www.jianshu.com/p/ea9a482ece5f

由于同一進程的多個線程共享同一片存儲空間,在帶來方便的同時,也帶來了訪問沖突這個嚴重的問題。Java語言提供了專門機制以解決這種沖突,有效避免了同一個數據對象被多個線程同時訪問。
需要明確的幾個問題:

  • synchronized關鍵字可以作為函數的修飾符,也可作為函數內的語句,也就是平時說的同步方法和同步語句塊。如果 再細的分類,synchronized可作用于instance變量、object reference(對象引用)、static函數和class literals(類名稱字面常量)身上。
  • 無論synchronized關鍵字加在方法上還是對象上,它取得的鎖都是對象,而不是把一段代碼或函數當作鎖――而且同步方法很可能還會被其他線程的對象訪問。
  • 每個對象只有一個鎖(lock)與之相關聯。
  • 實現同步是要很大的系統開銷作為代價的,甚至可能造成死鎖,所以盡量避免無謂的同步控制。

synchronized關鍵字的作用域有二種:

  • 某個對象實例內,synchronized aMethod(){}可以防止多個線程同時訪問這個對象的synchronized方法(如果一個對象有多個synchronized方法,只要一個線 程訪問了其中的一個synchronized方法,其它線程不能同時訪問這個對象中任何一個synchronized方法)。這時,不同的對象實例的 synchronized方法是不相干擾的。也就是說,其它線程照樣可以同時訪問相同類的另一個對象實例中的synchronized方法;
  • 某個類的范圍,synchronized static aStaticMethod{}防止多個線程同時訪問這個類中的synchronized static 方法。它可以對類的所有對象實例起作用。
  • synchronized 方法

    每個類實例對應一把鎖,每個 synchronized 方法都必須獲得調用該方法的類實例的鎖方能執行,否則所屬線程阻塞,方法一旦執行,就獨占該鎖,直到從該方法返回時才將鎖釋放,此后被阻塞的線程方能獲得該鎖,重新進入可執行狀態。這種機制確保了同一時刻對于每一個類實例,其所有聲明為 synchronized 的成員函數中至多只有一個處于可執行狀態(因為至多只有一個能夠獲得該類實例對應的鎖),從而有效避免了類成員變量的訪問沖突(只要所有可能訪問類成員變量的方法均被聲明為 synchronized)。
    在 Java 中,不光是類實例,每一個類也對應一把鎖,這樣我們也可將類的靜態成員函數聲明為 synchronized ,以控制其對類的靜態成員變量的訪問。

    synchronized 方法的缺陷

    同步方法,這時synchronized鎖定的是哪個對象呢?它鎖定的是調用這個同步方法對象。也就是說,當一個對象 P1在不同的線程中執行這個同步方法時,它們之間會形成互斥,達到同步的效果。但是這個對象所屬的Class所產生的另一對象P2卻可以任意調用這個被加 了synchronized關鍵字的方法.同步方法實質是將synchronized作用于object reference。――那個拿到了P1對象鎖的線程,才可以調用P1的同步方法,而對P2而言,P1這個鎖與它毫不相干,程序也可能在這種情形下擺脫同步機制的控制,造成數據混亂:(
    ;若將一個大的方法聲明為synchronized 將會大大影響效率,典型地,若將線程類的方法 run() 聲明為 synchronized ,由于在線程的整個生命期內它一直在運行,因此將導致它對本類任何 synchronized 方法的調用都永遠不會成功。當然我們可以通過將訪問類成員變量的代碼放到專門的方法中,將其聲明為 synchronized ,并在主方法中調用來解決這一問題,但是 Java 為我們提供了更好的解決辦法,那就是 synchronized 塊。

    synchronized 代碼塊

    除了方法前用synchronized關鍵字,synchronized關鍵字還可以用于方法中的某個區塊中,表示只對這個區塊的資源實行互斥訪問。用法是: synchronized(this){/區塊/},它的作用域是當前對象。
    這時鎖就是對象,誰拿到這個鎖誰就可以運行它所控制的那段代碼。當有一個明確的對象作為鎖時,就可以這樣寫程序,但當沒有明確的對象作為鎖,只是想讓一段代碼同步時,可以創建一個特殊的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行操作碼。

    synchronized 靜態方法

    將synchronized作用于static 函數,示例代碼如下:

    Class Foo {// 同步的static 函數public synchronized static void methodAAA() {//….}public void methodBBB() {synchronized(Foo.class) // class literal(類名稱字面常量)} }

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

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

    ?

    文/DanieX(簡書作者)
    原文鏈接:http://www.jianshu.com/p/ea9a482ece5f
    著作權歸作者所有,轉載請聯系作者獲得授權,并標注“簡書作者”。

    下面是另一篇博客,寫得也不錯。

    來自: http://zhangjunhd.blog.51cto.com/113473/70300/

    在并發環境下,解決共享資源沖突問題時,可以考慮使用鎖機制。

    1.對象的鎖

    所有對象都自動含有單一的鎖。

    JVM負責跟蹤對象被加鎖的次數。如果一個對象被解鎖,其計數變為0。在任務(線程)第一次給對象加鎖的時候,計數變為1。每當這個相同的任務(線程)在此對象上獲得鎖時,計數會遞增。

    只有首先獲得鎖的任務(線程)才能繼續獲取該對象上的多個鎖。

    每當任務離開一個synchronized方法,計數遞減,當計數為0的時候,鎖被完全釋放,此時別的任務就可以使用此資源。

    2.synchronized同步塊

    2.1同步到單一對象鎖

    當使用同步塊時,如果方法下的同步塊都同步到一個對象上的鎖,則所有的任務(線程)只能互斥的進入這些同步塊。

    Resource1.java演示了三個線程(包括main線程)試圖進入某個類的三個不同的方法的同步塊中,雖然這些同步塊處在不同的方法中,但由于是同步到同一個對象(當前對象?synchronized?(this)),所以對它們的方法依然是互斥的。

    Resource1.java

    package?com.zj.lock;

    import?java.util.concurrent.TimeUnit;

    ?

    public?class?Resource1 {

    ????public?void?f() {

    ???????// other operations should not be locked...

    ???????System.out.println(Thread.currentThread().getName()

    ??????????????+?":not synchronized in f()");

    ???????synchronized?(this) {

    ???????????for?(int?i = 0; i < 5; i++) {

    ??????????????System.out.println(Thread.currentThread().getName()

    ?????????????????????+?":synchronized in f()");

    ??????????????try?{

    ??????????????????TimeUnit.SECONDS.sleep(3);

    ??????????????}?catch?(InterruptedException e) {

    ??????????????????e.printStackTrace();

    ??????????????}

    ???????????}

    ???????}

    ????}

    ?

    ????public?void?g() {

    ???????// other operations should not be locked...

    ???????System.out.println(Thread.currentThread().getName()

    ??????????????+?":not synchronized in g()");

    ???????synchronized?(this) {

    ???????????for?(int?i = 0; i < 5; i++) {

    ??????????????System.out.println(Thread.currentThread().getName()

    ?????????????????????+?":synchronized in g()");

    ??????????????try?{

    ??????????????????TimeUnit.SECONDS.sleep(3);

    ??????????????}?catch?(InterruptedException e) {

    ??????????????????e.printStackTrace();

    ??????????????}

    ???????????}

    ???????}

    ????}

    ?

    ????public?void?h() {

    ???????// other operations should not be locked...

    ???????System.out.println(Thread.currentThread().getName()

    ??????????????+?":not synchronized in h()");

    ???????synchronized?(this) {

    ???????????for?(int?i = 0; i < 5; i++) {

    ??????????????System.out.println(Thread.currentThread().getName()

    ?????????????????????+?":synchronized in h()");

    ??????????????try?{

    ??????????????????TimeUnit.SECONDS.sleep(3);

    ??????????????}?catch?(InterruptedException e) {

    ??????????????????e.printStackTrace();

    ??????????????}

    ???????????}

    ???????}

    ????}

    ?

    ????public?static?void?main(String[] args) {

    ???????final?Resource1 rs =?new?Resource1();

    ?

    ???????new?Thread() {

    ???????????public?void?run() {

    ??????????????rs.f();

    ???????????}

    ???????}.start();

    ?

    ???????new?Thread() {

    ???????????public?void?run() {

    ??????????????rs.g();

    ???????????}

    ???????}.start();

    ?

    ???????rs.h();

    ????}

    }

    結果:

    Thread-0:not synchronized in f()

    Thread-0:synchronized in f()

    main:not synchronized in h()

    Thread-1:not synchronized in g()

    Thread-0:synchronized in f()

    Thread-0:synchronized in f()

    Thread-0:synchronized in f()

    Thread-0:synchronized in f()

    Thread-1:synchronized in g()

    Thread-1:synchronized in g()

    Thread-1:synchronized in g()

    Thread-1:synchronized in g()

    Thread-1:synchronized in g()

    main:synchronized in h()

    main:synchronized in h()

    main:synchronized in h()

    main:synchronized in h()

    main:synchronized in h()

    2.2?同步到多個對象鎖

    Resource1.java演示了三個線程(包括main線程)試圖進入某個類的三個不同的方法的同步塊中,這些同步塊處在不同的方法中,并且是同步到三個不同的對象(synchronized?(this),synchronized(syncObject1),synchronized?(syncObject2)),所以對它們的方法中的臨界資源訪問是獨立的。

    Resource2.java

    package?com.zj.lock;

    import?java.util.concurrent.TimeUnit;

    ?

    public?class?Resource2 {

    ????private?Object?syncObject1?=?new?Object();

    ????private?Object?syncObject2?=?new?Object();

    ?

    ????public?void?f() {

    ???????// other operations should not be locked...

    ???????System.out.println(Thread.currentThread().getName()

    ??????????????+?":not synchronized in f()");

    ???????synchronized?(this) {

    ???????????for?(int?i = 0; i < 5; i++) {

    ??????????????System.out.println(Thread.currentThread().getName()

    ?????????????????????+?":synchronized in f()");

    ??????????????try?{

    ??????????????????TimeUnit.SECONDS.sleep(3);

    ??????????????}?catch?(InterruptedException e) {

    ??????????????????e.printStackTrace();

    ??????????????}

    ???????????}

    ???????}

    ????}

    ?

    ????public?void?g() {

    ???????// other operations should not be locked...

    ???????System.out.println(Thread.currentThread().getName()

    ??????????????+?":not synchronized in g()");

    ???????synchronized?(syncObject1) {

    ???????????for?(int?i = 0; i < 5; i++) {

    ??????????????System.out.println(Thread.currentThread().getName()

    ?????????????????????+?":synchronized in g()");

    ??????????????try?{

    ??????????????????TimeUnit.SECONDS.sleep(3);

    ??????????????}?catch?(InterruptedException e) {

    ??????????????????e.printStackTrace();

    ??????????????}

    ???????????}

    ???????}

    ????}

    ?

    ????public?void?h() {

    ???????// other operations should not be locked...

    ???????System.out.println(Thread.currentThread().getName()

    ??????????????+?":not synchronized in h()");

    ???????synchronized?(syncObject2) {

    ???????????for?(int?i = 0; i < 5; i++) {

    ??????????????System.out.println(Thread.currentThread().getName()

    ?????????????????????+?":synchronized in h()");

    ??????????????try?{

    ??????????????????TimeUnit.SECONDS.sleep(3);

    ??????????????}?catch?(InterruptedException e) {

    ??????????????????e.printStackTrace();

    ??????????????}

    ???????????}

    ???????}

    ????}

    ?

    ????public?static?void?main(String[] args) {

    ???????final?Resource2 rs =?new?Resource2();

    ?

    ???????new?Thread() {

    ???????????public?void?run() {

    ??????????????rs.f();

    ???????????}

    ???????}.start();

    ?

    ???????new?Thread() {

    ???????????public?void?run() {

    ??????????????rs.g();

    ???????????}

    ???????}.start();

    ?

    ???????rs.h();

    ????}

    }

    結果:

    Thread-0:not synchronized in f()

    Thread-0:synchronized in f()

    main:not synchronized in h()

    main:synchronized in h()

    Thread-1:not synchronized in g()

    Thread-1:synchronized in g()

    Thread-0:synchronized in f()

    main:synchronized in h()

    Thread-1:synchronized in g()

    Thread-0:synchronized in f()

    main:synchronized in h()

    Thread-1:synchronized in g()

    Thread-0:synchronized in f()

    main:synchronized in h()

    Thread-1:synchronized in g()

    Thread-0:synchronized in f()

    main:synchronized in h()

    Thread-1:synchronized in g()

    3.Lock對象鎖

    除了使用synchronized外,還可以使用Lock對象來創建臨界區。Resource3.java的演示效果同Resource1.java;Resource4.java的演示效果同Resource2.java。

    Resource3.java

    package?com.zj.lock;

    import?java.util.concurrent.TimeUnit;

    import?java.util.concurrent.locks.Lock;

    import?java.util.concurrent.locks.ReentrantLock;

    ?

    public?class?Resource3 {

    ????private?Lock?lock?=?new?ReentrantLock();

    ?

    ????public?void?f() {

    ???????// other operations should not be locked...

    ???????System.out.println(Thread.currentThread().getName()

    ??????????????+?":not synchronized in f()");

    ???????lock.lock();

    ???????try?{

    ???????????for?(int?i = 0; i < 5; i++) {

    ??????????????System.out.println(Thread.currentThread().getName()

    ?????????????????????+?":synchronized in f()");

    ??????????????try?{

    ??????????????????TimeUnit.SECONDS.sleep(3);

    ??????????????}?catch?(InterruptedException e) {

    ??????????????????e.printStackTrace();

    ??????????????}

    ???????????}

    ???????}?finally?{

    ???????????lock.unlock();

    ???????}

    ????}

    ?

    ????public?void?g() {

    ???????// other operations should not be locked...

    ???????System.out.println(Thread.currentThread().getName()

    ??????????????+?":not synchronized in g()");

    ???????lock.lock();

    ???????try?{

    ???????????for?(int?i = 0; i < 5; i++) {

    ??????????????System.out.println(Thread.currentThread().getName()

    ?????????????????????+?":synchronized in g()");

    ??????????????try?{

    ??????????????????TimeUnit.SECONDS.sleep(3);

    ??????????????}?catch?(InterruptedException e) {

    ??????????????????e.printStackTrace();

    ??????????????}

    ???????????}

    ???????}?finally?{

    ???????????lock.unlock();

    ???????}

    ????}

    ?

    ????public?void?h() {

    ???????// other operations should not be locked...

    ???????System.out.println(Thread.currentThread().getName()

    ??????????????+?":not synchronized in h()");

    ???????lock.lock();

    ???????try?{

    ???????????for?(int?i = 0; i < 5; i++) {

    ??????????????System.out.println(Thread.currentThread().getName()

    ?????????????????????+?":synchronized in h()");

    ??????????????try?{

    ??????????????????TimeUnit.SECONDS.sleep(3);

    ??????????????}?catch?(InterruptedException e) {

    ??????????????????e.printStackTrace();

    ??????????????}

    ???????????}

    ???????}?finally?{

    ???????????lock.unlock();

    ???????}

    ????}

    ?

    ????public?static?void?main(String[] args) {

    ???????final?Resource3 rs =?new?Resource3();

    ?

    ???????new?Thread() {

    ???????????public?void?run() {

    ??????????????rs.f();

    ???????????}

    ???????}.start();

    ?

    ???????new?Thread() {

    ???????????public?void?run() {

    ??????????????rs.g();

    ???????????}

    ???????}.start();

    ?

    ???????rs.h();

    ????}

    }

    結果:

    Thread-0:not synchronized in f()

    Thread-0:synchronized in f()

    main:not synchronized in h()

    Thread-1:not synchronized in g()

    Thread-0:synchronized in f()

    Thread-0:synchronized in f()

    Thread-0:synchronized in f()

    Thread-0:synchronized in f()

    main:synchronized in h()

    main:synchronized in h()

    main:synchronized in h()

    main:synchronized in h()

    main:synchronized in h()

    Thread-1:synchronized in g()

    Thread-1:synchronized in g()

    Thread-1:synchronized in g()

    Thread-1:synchronized in g()

    Thread-1:synchronized in g()

    Resource4.java

    package?com.zj.lock;

    import?java.util.concurrent.TimeUnit;

    import?java.util.concurrent.locks.Lock;

    import?java.util.concurrent.locks.ReentrantLock;

    ?

    public?class?Resource4 {

    ????private?Lock?lock1?=?new?ReentrantLock();

    ????private?Lock?lock2?=?new?ReentrantLock();

    ????private?Lock?lock3?=?new?ReentrantLock();

    ?

    ????public?void?f() {

    ???????// other operations should not be locked...

    ???????System.out.println(Thread.currentThread().getName()

    ??????????????+?":not synchronized in f()");

    ???????lock1.lock();

    ???????try?{

    ???????????for?(int?i = 0; i < 5; i++) {

    ??????????????System.out.println(Thread.currentThread().getName()

    ?????????????????????+?":synchronized in f()");

    ??????????????try?{

    ??????????????????TimeUnit.SECONDS.sleep(3);

    ??????????????}?catch?(InterruptedException e) {

    ??????????????????e.printStackTrace();

    ??????????????}

    ???????????}

    ???????}?finally?{

    ???????????lock1.unlock();

    ???????}

    ????}

    ?

    ????public?void?g() {

    ???????// other operations should not be locked...

    ???????System.out.println(Thread.currentThread().getName()

    ??????????????+?":not synchronized in g()");

    ???????lock2.lock();

    ???????try?{

    ???????????for?(int?i = 0; i < 5; i++) {

    ??????????????System.out.println(Thread.currentThread().getName()

    ?????????????????????+?":synchronized in g()");

    ??????????????try?{

    ??????????????????TimeUnit.SECONDS.sleep(3);

    ??????????????}?catch?(InterruptedException e) {

    ??????????????????e.printStackTrace();

    ??????????????}

    ???????????}

    ???????}?finally?{

    ???????????lock2.unlock();

    ???????}

    ????}

    ?

    ????public?void?h() {

    ???????// other operations should not be locked...

    ???????System.out.println(Thread.currentThread().getName()

    ??????????????+?":not synchronized in h()");

    ???????lock3.lock();

    ???????try?{

    ???????????for?(int?i = 0; i < 5; i++) {

    ??????????????System.out.println(Thread.currentThread().getName()

    ?????????????????????+?":synchronized in h()");

    ??????????????try?{

    ??????????????????TimeUnit.SECONDS.sleep(3);

    ??????????????}?catch?(InterruptedException e) {

    ??????????????????e.printStackTrace();

    ??????????????}

    ???????????}

    ???????}?finally?{

    ???????????lock3.unlock();

    ???????}

    ????}

    ?

    ????public?static?void?main(String[] args) {

    ???????final?Resource4 rs =?new?Resource4();

    ?

    ???????new?Thread() {

    ???????????public?void?run() {

    ??????????????rs.f();

    ???????????}

    ???????}.start();

    ?

    ???????new?Thread() {

    ???????????public?void?run() {

    ??????????????rs.g();

    ???????????}

    ???????}.start();

    ?

    ???????rs.h();

    ????}

    }

    結果:

    Thread-0:not synchronized in f()

    Thread-0:synchronized in f()

    main:not synchronized in h()

    main:synchronized in h()

    Thread-1:not synchronized in g()

    Thread-1:synchronized in g()

    Thread-0:synchronized in f()

    main:synchronized in h()

    Thread-1:synchronized in g()

    Thread-0:synchronized in f()

    main:synchronized in h()

    Thread-1:synchronized in g()

    Thread-0:synchronized in f()

    main:synchronized in h()

    Thread-1:synchronized in g()

    Thread-0:synchronized in f()

    main:synchronized in h()

    Thread-1:synchronized in g()

    ?

    from:?https://www.cnblogs.com/beiyetengqing/p/6213437.html

    總結

    以上是生活随笔為你收集整理的Java synchronized 详解的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。