[轉載] java synchronized靜態同步方法與非靜態同步方法,同步語句塊

參考鏈接: Java中的靜態方法與實例方法

java synchronized靜態同步方法與非靜態同步方法,同步語句塊??

?

? 并發編程

? 線程同步

? 靜態方法鎖

? 非靜態方法鎖

? 同步塊?

??

?

?

? ? ? ? ? 進行多線程編程,同步控制是非常重要的,而同步控制就涉及到了鎖。?

? ? ? ? ?對代碼進行同步控制我們可以選擇同步方法,也可以選擇同步塊,這兩種方式各有優缺點,至于具體選擇什么方式,就見仁見智了,同步塊不僅可以更加精確的控制對象鎖,也就是控制鎖的作用域,何謂鎖的作用域?鎖的作用域就是從鎖被獲取到其被釋放的時間。而且可以選擇要獲取哪個對象的對象鎖。但是如果在使用同步塊機制時,如果使用過多的鎖也會容易引起死鎖問題,同時獲取和釋放所也有代價,而同步方法,它們所擁有的鎖就是該方法所屬的類的對象鎖,換句話說,也就是this對象,而且鎖的作用域也是整個方法,這可能導致其鎖的作用域可能太大,也有可能引起死鎖,同時因為可能包含了不需要進行同步的代碼塊在內,也會降低程序的運行效率。而不管是同步方法還是同步塊,我們都不應該在他們的代碼塊內包含無限循環,如果代碼內部要是有了無限循環,那么這個同步方法或者同步塊在獲取鎖以后因為代碼會一直不停的循環著運行下去,也就沒有機會釋放它所獲取的鎖,而其它等待這把鎖的線程就永遠無法獲取這把鎖,這就造成了一種死鎖現象。?

? ? ? 詳細解說一下同步方法的鎖,同步方法分為靜態同步方法與非靜態同步方法。?

? ? ? ? ?所有的非靜態同步方法用的都是同一把鎖——實例對象本身,也就是說如果一個實例對象的非靜態同步方法獲取鎖后,該實例對象的其他非靜態同步方法必須等待獲取鎖的方法釋放鎖后才能獲取鎖,可是別的實例對象的非靜態同步方法因為跟該實例對象的非靜態同步方法用的是不同的鎖,所以毋須等待該實例對象已獲取鎖的非靜態同步方法釋放鎖就可以獲取他們自己的鎖。?

? ? ? ? ? 而所有的靜態同步方法用的也是同一把鎖——類對象本身,這兩把鎖是兩個不同的對象,所以靜態同步方法與非靜態同步方法之間是不會有競態條件的。但是一旦一個靜態同步方法獲取鎖后,其他的靜態同步方法都必須等待該方法釋放鎖后才能獲取鎖,而不管是同一個實例對象的靜態同步方法之間,還是不同的實例對象的靜態同步方法之間,只要它們同一個類的實例對象!?

? ? ? 而對于同步塊,由于其鎖是可以選擇的,所以只有使用同一把鎖的同步塊之間才有著競態條件,這就得具體情況具體分析了,但這里有個需要注意的地方,同步塊的鎖是可以選擇的,但是不是可以任意選擇的!!!!這里必須要注意一個物理對象和一個引用對象的實例變量之間的區別!使用一個引用對象的實例變量作為鎖并不是一個好的選擇,因為同步塊在執行過程中可能會改變它的值,其中就包括將其設置為null,而對一個null對象加鎖會產生異常,并且對不同的對象加鎖也違背了同步的初衷!這看起來是很清楚的,但是一個經常發生的錯誤就是選用了錯誤的鎖對象,因此必須注意:同步是基于實際對象而不是對象引用的!多個變量可以引用同一個對象,變量也可以改變其值從而指向其他的對象,因此,當選擇一個對象鎖時,我們要根據實際對象而不是其引用來考慮!作為一個原則,不要選擇一個可能會在鎖的作用域中改變值的實例變量作為鎖對象!!!!?

? ??

? Java線程:線程的同步與鎖?

? ?

?

? ?

??

?

? ?

??

?

? ?

??

?

? 一、同步問題提出

??

?

? ?

??

?

? 線程的同步是為了防止多個線程訪問一個數據對象時,對數據造成的破壞。

??

?

? 例如:兩個線程ThreadA、ThreadB都操作同一個對象Foo對象,并修改Foo對象上的數據。

??

?

? ?

??

?

? public?

? class Foo {?

? ? ? ?

? private?

? int x = 100;?

? ?

? ? ? ?

? public?

? int getX() {?

? ? ? ? ? ?

? return x;?

? ? ? ?}?

? ?

? ? ? ?

? public?

? int fix(

? int y) {?

? ? ? ? ? ?x = x - y;?

? ? ? ? ? ?

? return x;?

? ? ? ?}?

? ?}

??

?

? ?

??

?

? public?

? class MyRunnable?

? implements Runnable {?

? ? ? ?

? private Foo foo =?

? new Foo();?

? ?

? ? ? ?

? public?

? static?

? void main(String[] args) {?

? ? ? ? ? ?MyRunnable r =?

? new MyRunnable();?

? ? ? ? ? ?Thread ta =?

? new Thread(r,?

? "Thread-A");?

? ? ? ? ? ?Thread tb =?

? new Thread(r,?

? "Thread-B");?

? ? ? ? ? ?ta.start();?

? ? ? ? ? ?tb.start();?

? ? ? ?}?

? ?

? ? ? ?

? public?

? void run() {?

? ? ? ? ? ?

? for (

? int i = 0; i < 3; i++) {?

? ? ? ? ? ? ? ?

? this.fix(30);?

? ? ? ? ? ? ? ?

? try {?

? ? ? ? ? ? ? ? ? ?Thread.sleep(1);?

? ? ? ? ? ? ? ?}?

? catch (InterruptedException e) {?

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

? ? ? ? ? ? ? ?}?

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

? " : 當前foo對象的x值= " + foo.getX());?

? ? ? ? ? ?}?

? ? ? ?}?

? ?

? ? ? ?

? public?

? int fix(

? int y) {?

? ? ? ? ? ?

? return foo.fix(y);?

? ? ? ?}?

? ?}

??

?

? ?

??

?

? 運行結果:

??

?

? Thread-A : 當前foo對象的x值= 40?

? ?Thread-B : 當前foo對象的x值= 40?

? ?Thread-B : 當前foo對象的x值= -20?

? ?Thread-A : 當前foo對象的x值= -50?

? ?Thread-A : 當前foo對象的x值= -80?

? ?Thread-B : 當前foo對象的x值= -80?

? ?

? ?Process finished with exit code 0

??

?

? ?

??

?

? ? ? ? ? ? 從結果發現,這樣的輸出值明顯是不合理的。原因是兩個線程不加控制的訪問Foo對象并修改其數據所致。

??

?

? ?

??

?

? ? ? ? ? 如果要保持結果的合理性,只需要達到一個目的,就是將對Foo的訪問加以限制,每次只能有一個線程在訪問。這樣就能保證Foo對象中數據的合理性了。

??

?

? ?

??

?

? 在具體的Java代碼中需要完成一下兩個操作:

??

?

? 把競爭訪問的資源類Foo變量x標識為private;

??

?

? 同步哪些修改變量的代碼,使用synchronized關鍵字同步方法或代碼。

??

?

? ?

??

?

? 二、同步和鎖定

??

?

? ?

??

?

? 1、鎖的原理

??

?

? ?

??

?

? Java中每個對象都有一個內置鎖

??

?

? ?

??

?

? ? ? ? ??

? ?當程序運行到非靜態的synchronized同步方法上時,自動獲得與正在執行代碼類的當前實例(this實例)有關的鎖。獲得一個對象的鎖也稱為獲取鎖、鎖定對象、在對象上鎖定或在對象上同步。

??

?

? ?

??

?

? 當程序運行到synchronized同步方法或代碼塊時才該對象鎖才起作用。

??

?

? ?

??

?

? ? ? ? ? ? ??

? 一個對象只有一個鎖。所以,如果一個線程獲得該鎖,就沒有其他線程可以獲得鎖,直到第一個線程釋放(或返回)鎖。這也意味著任何其他線程都不能進入該對象上的synchronized方法或代碼塊,直到該鎖被釋放。

??

?

? ?

??

?

? 釋放鎖是指持鎖線程退出了synchronized同步方法或代碼塊。

??

?

? ?

??

?

? 關于鎖和同步,有一下幾個要點:

??

?

? 1)、

? 只能同步方法,而不能同步變量和類;

??

?

? 2

? )、每個對象只有一個鎖;當提到同步時,應該清楚在什么上同步?也就是說,在哪個對象上同步?

??

?

? 3)、

? 不必同步類中所有的方法,類可以同時擁有同步和非同步方法。

??

?

? 4)

? 、如果兩個線程要執行一個類中的synchronized方法,并且兩個線程使用相同的實例來調用方法,那么一次只能有一個線程能夠執行方法,另一個需要等待,直到鎖被釋放。也就是說:如果一個線程在對象上獲得一個鎖,就沒有任何其他線程可以進入(該對象的)類中的任何一個同步方法。

??

?

? 5)、

? 如果線程擁有同步和非同步方法,則非同步方法可以被多個線程自由訪問而不受鎖的限制。

??

? 6)、線程睡眠時,它所持的任何鎖都不會釋放。?

?

? 7

? )、線程可以獲得多個重進入(synchronized )鎖。比如,在一個對象的同步方法里面調用另外一個對象的同步方法,則獲取了兩個對象的同步鎖。

??

? ?

?

? 8)、同步損害并發性,應該盡可能縮小同步范圍。同步不但可以同步整個方法,還可以同步方法中一部分代碼塊。

??

?

? 9

? )、在使用同步代碼塊時候,應該指定在哪個對象上同步,也就是說要獲取哪個對象的鎖。例如:

??

?

? ? ? public int fix(int y) {

? ? ? ? ? ?synchronized (this) {

? ? ? ? ? ? ? ?x = x - y;

? ? ? ? ? ?}

? ? ? ? ? ?return x;

? ? ? ?}

??

?

? ?

??

?

? 當然,同步方法也可以改寫為非同步方法,但功能完全一樣的,例如:

??

?

? ? ? public synchronized int getX() {? ? ? ? ?return x++;? ? ?}

??

?

? 與

??

?

? ? ? public int getX() {? ? ? ? ?synchronized (this) {? ? ? ? ? ? ?return x;? ? ? ? ?}? ? ?}

??

?

? 效果是完全一樣的。

??

?

? ?

??

?

? 三、靜態方法同步

??

?

? ?

??

?

? 要同步靜態方法,需要一個用于整個類對象的鎖,這個對象是就是這個類(XXX.class)。

??

?

? 例如:

??

?

? public static synchronized int setName(String name){

??

?

? ? ? ? Xxx.name = name;

??

?

? }

??

?

? 等價于 public static int setName(String name){? ? ? ?synchronized(Xxx.class){? ? ? ? ? ? ?Xxx.name = name;? ? ? ?} }

??

?

? ??

??

?

? 四、如果線程不能不能獲得鎖會怎么樣

??

?

? ?

??

?

? ? ? ? ?如果線程試圖進入同步方法,而其鎖已經被占用,則線程在該對象上被阻塞。實質上,線程進入該對象的的一種池中,必須在哪里等待,直到其鎖被釋放,該線程再次變為可運行或運行為止。

??

?

? ?

??

?

? 當考慮阻塞時,一定要注意哪個對象正被用于鎖定:

??

?

? 1、調用同一個對象中非靜態同步方法的線程將彼此阻塞。如果是不同對象,則每個線程有自己的對象的鎖,線程間彼此互不干預。

??

?

? ?

??

?

? 2、調用同一個類中的靜態同步方法的線程將彼此阻塞,它們都是鎖定在相同的Class對象上。

??

?

? ?

??

?

? 3

? 、靜態同步方法和非靜態同步方法將永遠不會彼此阻塞,因為靜態方法鎖定在Class對象上,非靜態方法鎖定在該類的對象上。

??

?

? ?

??

?

? 4、對于同步代碼塊,要看清楚什么對象已經用于鎖定(synchronized后面括號的內容)。在同一個對象上進行同步的線程將彼此阻塞,在不同對象上鎖定的線程將永遠不會彼此阻塞。

??

?

? ?

??

?

? 五、何時需要同步

??

?

? ?

??

?

? ? ? ? 在多個線程同時訪問互斥(可交換)數據時,應該同步以保護數據,確保兩個線程不會同時修改更改它。

??

?

? ?

??

?

? 對于非靜態字段中可更改的數據,通常使用非靜態方法訪問。

??

??

??

? ?對于靜態字段中可更改的數據,通常使用靜態方法訪問。

? ?

??

? ??

? ?

??

? ?如果需要在非靜態方法中使用靜態字段,或者在靜態字段中調用非靜態方法,問題將變得非常復雜。已經超出SJCP考試范圍了。

? ?

??

? ??

? ?

??

? ?六、線程安全類

? ?

??

? ??

? ?

??

? ? ? ? ?當一個類已經很好的同步以保護它的數據時,這個類就稱為“線程安全的”。

? ?

??

? ? 即使是線程安全類,也應該特別小心,因為操作的線程是間仍然不一定安全。

? ?

??

? ??

? ?

??

? ?舉個形象的例子,比如一個集合是線程安全的,有兩個線程在操作同一個集合對象,當第一個線程查詢集合非空后,刪除集合中所有元素的時候。第二個線程也來執行與第一個線程相同的操作,也許在第一個線程查詢后,第二個線程也查詢出集合非空,但是當第一個執行清除后,第二個再執行刪除顯然是不對的,因為此時集合已經為空了。

? ?

??

? ?看個代碼:

? ?

??

? ??

? ?

??

? ?public?

? ?class NameList {?

? ? ? ??

? ?private List nameList = Collections.synchronizedList(

? ?new LinkedList());?

? ??

? ? ? ??

? ?public?

? ?void add(String name) {?

? ? ? ? ? ? nameList.add(name);?

? ? ? ? }?

? ??

? ? ? ??

? ?public String removeFirst() {?

? ? ? ? ? ??

? ?if (nameList.size() > 0) {?

? ? ? ? ? ? ? ??

? ?return (String) nameList.remove(0);?

? ? ? ? ? ? }?

? ?else {?

? ? ? ? ? ? ? ??

? ?return?

? ?null;?

? ? ? ? ? ? }?

? ? ? ? }?

? ? }

? ?

??

? ??

? ?

??

? ?public?

? ?class Test {?

? ? ? ??

? ?public?

? ?static?

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

? ? ? ? ? ??

? ?final NameList nl =?

? ?new NameList();?

? ? ? ? ? ? nl.add(

? ?"aaa");?

? ? ? ? ? ??

? ?class NameDropper?

? ?extends Thread{?

? ? ? ? ? ? ? ??

? ?public?

? ?void run(){?

? ? ? ? ? ? ? ? ? ? String name = nl.removeFirst();?

? ? ? ? ? ? ? ? ? ? System.out.println(name);?

? ? ? ? ? ? ? ? }?

? ? ? ? ? ? }?

? ??

? ? ? ? ? ? Thread t1 =?

? ?new NameDropper();?

? ? ? ? ? ? Thread t2 =?

? ?new NameDropper();?

? ? ? ? ? ? t1.start();?

? ? ? ? ? ? t2.start();?

? ? ? ? }?

? ? }

? ?

??

? ??

? ?

??

? ?雖然集合對象

? ?

??

? ? ? ?private List nameList = Collections.synchronizedList(new LinkedList());是同步的,但是程序還不是線程安全的。出現這種事件的原因是,上例中一個線程操作列表過程中無法阻止另外一個線程對列表的其他操作。

? ?

??

? ??

? ?

??

? ?解決上面問題的辦法是,在操作集合對象的NameList上面做一個同步。改寫后的代碼如下:

? ?

??

? ?public?

? ?class NameList {?

? ? ? ??

? ?private List nameList = Collections.synchronizedList(

? ?new LinkedList());?

? ??

? ? ? ??

? ?public?

? ?synchronized?

? ?void add(String name) {?

? ? ? ? ? ? nameList.add(name);?

? ? ? ? }?

? ??

? ? ? ??

? ?public?

? ?synchronized String removeFirst() {?

? ? ? ? ? ??

? ?if (nameList.size() > 0) {?

? ? ? ? ? ? ? ??

? ?return (String) nameList.remove(0);?

? ? ? ? ? ? }?

? ?else {?

? ? ? ? ? ? ? ??

? ?return?

? ?null;?

? ? ? ? ? ? }?

? ? ? ? }?

? ? }

? ?

??

? ??

? ?

??

?

? 這樣,當一個線程訪問其中一個同步方法時,其他線程只有等待。

??

?

? ?

??

?

? 七、線程死鎖

??

?

? ?

??

?

? ? ? ? ?死鎖對Java程序來說,是很復雜的,也很難發現問題。當兩個線程被阻塞,每個線程在等待另一個線程時就發生死鎖。

??

?

? ?

??

?

? 還是看一個比較直觀的死鎖例子:

??

?

? ?

??

?

? public?

? class DeadlockRisk {?

? ? ? ?

? private?

? static?

? class Resource {?

? ? ? ? ? ?

? public?

? int value;?

? ? ? ?}?

? ?

? ? ? ?

? private Resource resourceA =?

? new Resource();?

? ? ? ?

? private Resource resourceB =?

? new Resource();?

? ?

? ? ? ?

? public?

? int read() {?

? ? ? ? ? ?

? synchronized (resourceA) {?

? ? ? ? ? ? ? ?

? synchronized (resourceB) {?

? ? ? ? ? ? ? ? ? ?

? return resourceB.value + resourceA.value;?

? ? ? ? ? ? ? ?}?

? ? ? ? ? ?}?

? ? ? ?}?

? ?

? ? ? ?

? public?

? void write(

? int a,?

? int b) {?

? ? ? ? ? ?

? synchronized (resourceB) {?

? ? ? ? ? ? ? ?

? synchronized (resourceA) {?

? ? ? ? ? ? ? ? ? ?resourceA.value = a;?

? ? ? ? ? ? ? ? ? ?resourceB.value = b;?

? ? ? ? ? ? ? ?}?

? ? ? ? ? ?}?

? ? ? ?}?

? ?}

??

?

? ?

??

?

? ? ? ? ? 假設read()方法由一個線程啟動,write()方法由另外一個線程啟動。讀線程將擁有resourceA鎖,寫線程將擁有resourceB鎖,兩者都堅持等待的話就出現死鎖。

??

?

? ?

??

?

? ? ? ? ? 實際上,上面這個例子發生死鎖的概率很小。因為在代碼內的某個點,CPU必須從讀線程切換到寫線程,所以,死鎖基本上不能發生。

??

?

? ?

??

?

? ? ? ? ? ?但是,無論代碼中發生死鎖的概率有多小,一旦發生死鎖,程序就死掉。有一些設計方法能幫助避免死鎖,包括始終按照預定義的順序獲取鎖這一策略。已經超出SCJP的考試范圍。

??

?

? ?

??

?

? 八、線程同步小結

??

?

? ?

??

?

? 1、線程同步的目的是為了保護多個線程反問一個資源時對資源的破壞。

??

?

? 2、

? 線程同步方法是通過鎖來實現,每個對象都有切僅有一個鎖,這個鎖與一個特定的對象關聯,線程一旦獲取了對象鎖,其他訪問該對象的線程就無法再訪問該對象的其他同步方法。

??

?

? 3、對于靜態同步方法,鎖是針對這個類的,鎖對象是該類的Class對象。靜態和非靜態方法的鎖互不干預。一個線程獲得鎖,當在一個同步方法中訪問另外對象上的同步方法時,會獲取這兩個對象鎖。

??

?

? 4、對于同步,要時刻清醒在哪個對象上同步,這是關鍵。

??

?

? 5、

? 編寫線程安全的類,需要時刻注意對多個線程競爭訪問資源的邏輯和安全做出正確的判斷,對“原子”操作做出分析,并保證原子操作期間別的線程無法訪問競爭資源。

??

?

? 6、當多個線程等待一個對象鎖時,沒有獲取到鎖的線程將發生阻塞。

??

?

? 7、死鎖是線程間相互等待鎖鎖造成的,在實際中發生的概率非常的小。真讓你寫個死鎖程序,不一定好使,呵呵。但是,一旦程序發生死鎖,程序將死掉。

??

? ?

? ??

? ??

? ??

? ??

??

? ?

? ?

? ? Java代碼??

? ??

? ??

? ?

? ?package com.etrip.concurrent.executor;? ? ? import java.util.Collections;? ?import java.util.HashMap;? ?import java.util.Iterator;? ?import java.util.Map;? ?import java.util.Map.Entry;? ?import java.util.Set;? ?/**? ?* 非靜態同步方法,靜態同步方法,同步語句塊的使用? ?*? ? *? ? * 進行多線程編程,同步控制是非常重要的,而同步控制就涉及到了鎖。? ? ? ? ? ? 對代碼進行同步控制我們可以選擇同步方法,也可以選擇同步塊,這兩種方式各有優缺點,至于具體選擇什么方式,就見仁見智了,同步塊不僅可以更加精確的控制對象鎖,也就是控制鎖的作用域,何謂鎖的作用域?鎖的作用域就是從鎖被獲取到其被釋放的時間。而且可以選擇要獲取哪個對象的對象鎖。但是如果在使用同步塊機制時,如果使用過多的鎖也會容易引起死鎖問題,同時獲取和釋放所也有代價,而同步方法,它們所擁有的鎖就是該方法所屬的類的對象鎖,換句話說,也就是this對象,而且鎖的作用域也是整個方法,這可能導致其鎖的作用域可能太大,也有可能引起死鎖,同時因為可能包含了不需要進行同步的代碼塊在內,也會降低程序的運行效率。而不管是同步方法還是同步塊,我們都不應該在他們的代碼塊內包含無限循環,如果代碼內部要是有了無限循環,那么這個同步方法或者同步塊在獲取鎖以后因為代碼會一直不停的循環著運行下去,也就沒有機會釋放它所獲取的鎖,而其它等待這把鎖的線程就永遠無法獲取這把鎖,這就造成了一種死鎖現象。? ? *? ? * @author longgangbai? ?*/? ?public class StaticInstanceLock {? ? ? ? ? ? ? ? ? ? ?private? ?int count;? ? ? ?private? static? StaticInstanceLock? instance=null;? ? ? ?private StaticInstanceLock(){? ? ? ?}? ? ? ?/**? ? ? ?* 靜態方法的鎖? ? ? ?*? ? ? ? * @return? ? ? ?*/? ? ? ?public static synchronized StaticInstanceLock getInstance(){? ? ? ? ? ?if(instance==null){? ? ? ? ? ? ? ?instance=new? StaticInstanceLock();? ? ? ? ? ?}? ? ? ? ? ?return instance;? ? ? ?}? ? ? ? ? /**? ? ? ?* 非靜態方法的鎖? ? ? ?* @return? ? ? ?*/? ? ? ?public synchronized int getCount(){? ? ? ? ? ?return count;? ? ? ?}? ? ? ? ? ? ? public synchronized? void setCount(int count){? ? ? ? ? ?this.count=count;? ? ? ?}? ? ? ?/**? ? ? ?* 同步語句塊的使用? ? ? ?*? ? ? ? */? ? ? ?public void synmethod(){? ? ? ? ? ? ? ? ?//HashMap為非安全性Map? ? ? ? ? ? ? ? ?HashMap<String,String> hashmap = new HashMap<String,String>();? ? ? ? ? ? ? ? ?hashmap.put("ZH","中國");? ? ? ? ? ? ? ? ?hashmap.put("EN","英國");? ? ? ? ? ? ? ? ?hashmap.put("AM","美國");? ? ? ? ? ? ? ? ?hashmap.put("FR","法國");? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //創建一個同步的對象Map? ? ? ? ? ? ? ? ?Map<String,String> m = Collections.synchronizedMap(hashmap);? ? ? ? ? ? ? ? ?Set<String> s = m.keySet();? // Needn't be in synchronized block? ? ? ? ? ? ? ? ?//這里同步的對象均為需要使用同步的對象如Map而非Set? ? ? ? ? ? ? ? ?synchronized(m) {? // Synchronizing on m, not s!? ? ? ? ? ? ? ? ? ? ?Iterator<String> i = s.iterator(); // Must be in synchronized block? ? ? ? ? ? ? ? ? ? ?while (i.hasNext()){? ? ? ? ? ? ? ? ? ? ? ? ?foo(i.next());? ? ? ? ? ? ? ? ? ? ?}? ? ? ? ? ? ? ? ?}? ? ? ?}? ? ? ? ? ? ? public void foo(String entry){? ? ? ? ? ?System.out.println("StaticInstanceLock ="+entry);? ? ? ?}? ? ? ? ? ? ? public static void main(String[] args) {? ? ? ? ? ? ? ? ? StaticInstanceLock instance=StaticInstanceLock.getInstance();? ? ? ? ? ?instance.setCount(7);? ? ? ? ? ?int count = instance.getCount();? ? ? ? ? ?instance.synmethod();? ? ? ?}? ? ? ? ? }

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/540316.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/540316.shtml
英文地址,請注明出處:http://en.pswp.cn/news/540316.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

SpringBoot安裝和創建簡單的Web應用

SpringBoot安裝 方式一&#xff1a; Eclipese->Help->Eclipse Marketplace ->Finde STS -> Install 注意&#xff1a;安裝過程中挺慢&#xff0c;而且可能會報錯&#xff0c;報錯時需要重復以上步驟&#xff08;重新安裝STS后&#xff0c;安裝進度接之前的繼續進行…

[轉載] JAVA 堆棧 堆 方法區 靜態區 final static 內存分配 詳解

參考鏈接&#xff1a; 在Java中為靜態最終static final變量分配值 轉載來源&#xff1a;https://blog.csdn.net/peterwin1987/article/details/7571808 Java棧與堆 堆:順序隨意 棧:后進先出(Last-in/First-Out). Java的堆是一個運行時數據區,類的對象從中分配空間。這些…

android學習之-Style樣式的定義

這個例子主要是寫了配置文件&#xff0c;main.xml <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android" android:orientation"vertical" android:lay…

[轉載] JAVA泛型雜談--擦除,協變,逆變,通配符等

參考鏈接&#xff1a; Java中的協變返回類型 在《JAVA核心思想》這本書里&#xff0c;關于泛型的章節意外的很多&#xff0c;小小的泛型里其實有很多可以學習的內容&#xff0c;我總結下最近看書的成果。 一. 泛型的好處和應用 最基礎的用到泛型的地方無非是在容器里 使用…

ASP.NET Session 詳解

[ASP.NET] Session 詳解 開發者在線 Builder.com.cn 更新時間:2008-03-23作者&#xff1a;黑暗凝聚力量&#xff0c;墮落方能自由 來源:CSDN 本文關鍵詞&#xff1a; Web開發 ASP session 詳解 本文僅代表作者個人觀點&#xff0c;正確與否請讀者自行研究&#xff01;閱讀本文…

[轉載] java給對象中的包裝類設置默認值

參考鏈接&#xff1a; Java中的對象類Object 處理方法如下 主要適用于&#xff0c;對象中使用了包裝類&#xff0c;但是不能給null需要有默認值的情況 /** * 處理對象中包裝類&#xff0c;因為快捷簽沒有用包裝類 * * param object 對象 */ public static void handlePara…

hadoop namenode管理元數據機制

一、簡要namenode管理元數據機制&#xff1a; 二、詳細namenode管理元數據機制&#xff1a; 三、secondary namenode 合并edits和fsimage&#xff1a; 四、namenode存儲元數據細節&#xff1a; 五、checkpoint觸發點&#xff1a; 本文轉自lzf0530377451CTO博客&#xff0c;原文…

[轉載] 多線程詳解java.util.concurrent

參考鏈接&#xff1a; java.lang.Object的靈活性 一、多線程 1、操作系統有兩個容易混淆的概念&#xff0c;進程和線程。 進程&#xff1a;一個計算機程序的運行實例&#xff0c;包含了需要執行的指令&#xff1b;有自己的獨立地址空間&#xff0c;包含程序內容和數據&#…

BABOK - 企業分析(Enterprise Analysis)概要

描述 企業分析描述我們如何捕捉、提煉并明晰業務需要&#xff0c;并定義一個可能實現這些業務需要的一個方案范圍&#xff0c;它包括問題定義和分析&#xff0c;業務案例開發&#xff0c;可行性研究和方案范圍定義 目的 明確業務戰略需要和目標&#xff0c;并建議方案范圍 任務…

6、EIGRP配置實驗之負載均衡

1、實驗拓撲 2、負載均衡原理 等價負載均衡&#xff1a;默認情況下EIGRP只支持等價負載均衡&#xff0c;默認支持4條線路的等價負載均衡&#xff0c;可以通過show ip protocols 查看&#xff0c;最大可以支持16條線路的等價負載均衡&#xff0c;可以在EIGRP路由進程下通過maxim…

[轉載] 詳解Java中靜態方法

參考鏈接&#xff1a; Java中的靜態類 定義&#xff1a; 在類中使用static修飾的靜態方法會隨著類的定義而被分配和裝載入內存中&#xff1b;而非靜態方法屬于對象的具體實例&#xff0c;只有在類的對象創建時在對象的內存中才有這個方法的代碼段。 注意&#xff1a; 非靜態…

[轉載] 向集合中添加自定義類型--建議在自定義類型的時候要重寫equals方法

參考鏈接&#xff1a; Java重寫equals方法 package com.bjpowernode.t01list; import java.util.ArrayList; /* * 向集合中添加自定義類型 */public class TestList04 { public static void main(String[] args) { ArrayList list new ArrayList(); Student s1 new Stude…

[轉載] java重寫toString()方法

參考鏈接&#xff1a; 在Java中重寫toString() 前言&#xff1a; 在你興高采烈的寫完一個類&#xff0c;創建測試類時&#xff0c;創建對象&#xff0c;傳入參數&#xff0c;調用對象&#xff0c;以為會得到參數值&#xff0c;但突然發現輸出的是“ 類名什么東東&#xff1f;&…

haproxy+keepalived實現負載均衡及高可用

HAProxy是一個使用C語言編寫的自由及開放源代碼軟件&#xff0c;其提供高性能性、負載均衡&#xff0c;以及基于TCP和HTTP的應用程序代理。相較與 Nginx&#xff0c;HAProxy 更專注與反向代理&#xff0c;因此它可以支持更多的選項&#xff0c;更精細的控制&#xff0c;更多的健…

[轉載] Java中變量與常量

參考鏈接&#xff1a; Java中的實例變量隱藏 1、變量的定義&#xff1a;定義變量就是要告訴編譯器這個變量的數據類型&#xff0c;這樣編譯器才知道需要分配多少空間給它&#xff0c;以及它能存放什么樣的數據。在程序運行過程中空間的值是變化的&#xff0c;這個內存空間就成…

Linux-實用快捷鍵操作

博文說明【前言】&#xff1a; 本文將通過個人口吻介紹Linux下一些常用的實用快捷鍵&#xff0c;在目前時間點【2017年6月14號】下&#xff0c;所掌握的技術水平有限&#xff0c;可能會存在不少知識理解不夠深入或全面&#xff0c;望大家指出問題共同交流&#xff0c;在后續工作…

iOS技術博客:App備案指南

&#x1f4dd; 摘要 本文介紹了移動應用程序&#xff08;App&#xff09;備案的重要性和流程。備案是規范App開發和運營的必要手段&#xff0c;有助于保護用戶權益、維護網絡安全和社會秩序。為了幫助開發者更好地了解備案流程&#xff0c;本文提供了一份最新、最全、最詳的備…

[轉載] Java中靜態成員變量,靜態代碼塊,靜態內部類何時被初始化?

參考鏈接&#xff1a; Java中的初始化程序塊Initializer Block 關于這個問題&#xff0c;本文不扯理論&#xff0c;直接上代碼&#xff0c;通過結果來驗證結論&#xff0c;廢話少說&#xff0c;測試代碼如下&#xff1a; public class StaticTest { public static StaticMem…

mikrotik dhcp server

操作路徑: /ip dhcp-server 關聯操作: /ip pool屬性 述 dhcp server interface (名稱) – 選擇 DHCP 服務的網絡接口 dhcp address space (IP 地址/掩碼; 默認: 192.168.0.0/24) – DHCP 服務器將出租給客戶端的網絡地 址段 gateway (IP 地址; 默認: 0.0.0.0) – 分配給客戶端的…

[轉載] Java static關鍵字與static{}語句塊

參考鏈接&#xff1a; Java中的靜態塊static block 目錄直通車 一、 類的加載特性與時機 1、 類加載的特性 2、 類加載的時機 二、 static的三個常用 1、 修飾成員變量 2、 修飾成員方法 3、 靜態塊&#xff08;static{}&#xff09; 一、 類的加載特性與時機 …