導航:首頁 > 編程語言 > java同步方法實現

java同步方法實現

發布時間:2023-08-03 11:33:06

A. java線程同步的方法

等待喚醒機制
wait():讓線程等待。將線程存儲到一個線程池中。
notify():喚醒被等待的線程。通常都喚醒線程池中的第一個。讓被喚醒的線程處於臨時阻塞狀態。
notifyAll(): 喚醒所有的等待線程。將線程池中的所有線程都喚醒,讓它們從凍結狀體轉到臨時阻塞狀態.
這三個方法用於操作線程,可是定義在了Object類中,為什麼呢?
因為,這三個方法在使用時,都需要定義在同步中,要明確這些方法所操作的線程所屬於鎖。
簡單說。在A鎖被wait的線程,只能被A鎖的notify方法喚醒。
所以必須要表示wait notify方法所屬的鎖對象,而鎖對象可以是任意的對象。
可以被任意的對象調用的方法肯定定義在Object類中。
注意:等待喚醒機制,通常都用在同步中,因為需要鎖的支持。
而且必須要明確wait notify 所作用的鎖對象。

JDK1.5後的鎖

在jdk1.5版本之後,
出現了一些新的特性,將原理的線程進行了改良。
在java.util.concurrent.locks包中提供了一個介面Lock。替代了synchronized。
synchronized。使用的是鎖操作是隱式的。
Lock介面,使用的鎖操作是顯示的。
由兩個方法來完成:
lock():獲取鎖。
unlock():釋放鎖。
還有一個對象,Condition.
該對象的出現替代了Object中的wait notify notifyAll這些操作監視器的方法。
替代後的方式:await signal signalAll.

B. Java多線程初學者指南(10):使用Synchronized關鍵字同步類方法

要想解決 臟數據 的問題 最簡單的方法就是使用synchronized關鍵字來使run方法同步 代碼如下

publicsynchronizedvoidrun(){}

從上面的代碼可以看出 只要在void和public之間加上synchronized關鍵字 就可以使run方法同步 也就是說 對於同一個Java類的對象實例 run方法同時只能被一個線程調用 並當前的run執行完後 才能被其他的線程調用 即使當前線程執行到了run方法中的yield方法 也只是暫停了一下 由於其他線程無法執行run方法 因此 最終還是會由當前的線程來繼續執行 先看看下面的代碼

sychronized關鍵字只和一個對象實例綁定

classTest{publicsynchronizedvoidmethod(){}納察}{privateTesttest;publicvoidrun() { thod(); } publicSync(Testtest) { this test=test; } publicstaticvoidmain(String[]args)throwsException { Testtest =newTest(); Testtest =newTest(); Syncsync =newSync(test ); Syncsync =newSync(test ); newThread(sync ) start(); newThread(sync ) start(); } }

在Test類中的method方法是同步的 但上面的代碼建立了兩個Test類的實例 因此 test 和test 的method方法是分別執行的 要想讓method同步 必須在建立仿茄升Sync類的實例時向它的構造方法中傳入同一個Test類的實例 如下面的代碼所示

Syncsync =newSync(test );

不僅可以使用synchronized來同步非靜態方法 也可以使用synchronized來同步靜態方法 如可以按如下方式來定義method方法

classTest{ (){}}

建立Test類的對象實例如下

Testtest=newTest();

對於靜態方法來說 只要加上了synchronized關鍵字 這個方法就是同步的 無論是使用thod() 還是使用thod()來調用method方法 method都是同步的 並不存在非靜態方法的多個實例的問題

在 種設計模式中的單件(Singleton)模式如果按傳統的方法設計 也是線程不安全的 下面的代碼是一個線程不安全的單件模式

packagetest;//線程安全的Singleton模式classSingleton{privatestaticSingletonsample;privateSingleton(){備老}(){if(sample==null){Thread yield();//為了放大Singleton模式的線程不安全性sample=newSingleton();}returnsample;}}{publicvoidrun(){Singletonsingleton=Singleton getInstance();System out println(singleton hashCode());}publicstaticvoidmain(String[]args){Threadthreads[]=newThread[ ];for(inti= ;i<threads length;i++)threads[i]=newMyThread();for(inti= ;i<threads length;i++)threads[i] start();}}

在上面的代碼調用yield方法是為了使單件模式的線程不安全性表現出來 如果將這行去掉 上面的實現仍然是線程不安全的 只是出現的可能性小得多

程序的運行結果如下

上面的運行結果可能在不同的運行環境上有所有同 但一般這五行輸出不會完全相同 從這個輸出結果可以看出 通過getInstance方法得到的對象實例是五個 而不是我們期望的一個 這是因為當一個線程執行了Thread yield()後 就將CPU資源交給了另外一個線程 由於在線程之間切換時並未執行到創建Singleton對象實例的語句 因此 這幾個線程都通過了if判斷 所以 就會產生了建立五個對象實例的情況(可能創建的是四個或三個對象實例 這取決於有多少個線程在創建Singleton對象之前通過了if判斷 每次運行時可能結果會不一樣)

要想使上面的單件模式變成線程安全的 只要為getInstance加上synchronized關鍵字即可 代碼如下

(){}

當然 還有更簡單的方法 就是在定義Singleton變數時就建立Singleton對象 代碼如下

=newSingleton();

然後在getInstance方法中直接將sample返回即可 這種方式雖然簡單 但不知在getInstance方法中創建Singleton對象靈活 讀者可以根據具體的需求選擇使用不同的方法來實現單件模式

在使用synchronized關鍵字時有以下四點需要注意

synchronized關鍵字不能繼承

雖然可以使用synchronized來定義方法 但synchronized並不屬於方法定義的一部分 因此 synchronized關鍵字不能被繼承 如果在父類中的某個方法使用了synchronized關鍵字 而在子類中覆蓋了這個方法 在子類中的這個方法默認情況下並不是同步的 而必須顯式地在子類的這個方法中加上synchronized關鍵字才可以 當然 還可以在子類方法中調用父類中相應的方法 這樣雖然子類中的方法不是同步的 但子類調用了父類的同步方法 因此 子類的方法也就相當於同步了 這兩種方式的例子代碼如下

在子類方法中加上synchronized關鍵字

classParent{ publicsynchronizedvoidmethod(){}}classChildextendsParent{ publicsynchronizedvoidmethod(){}}

在子類方法中調用父類的同步方法

classParent{ publicsynchronizedvoidmethod(){}}classChildextendsParent{publicvoidmethod(){thod();}}

在定義介面方法時不能使用synchronized關鍵字

構造方法不能使用synchronized關鍵字 但可以使用下節要討論的synchronized塊來進行同步

synchronized可以自由放置

在前面的例子中使用都是將synchronized關鍵字放在方法的返回類型前面 但這並不是synchronized可放置唯一位置 在非靜態方法中 synchronized還可以放在方法定義的最前面 在靜態方法中 synchronized可以放在static的前面 代碼如下

publicsynchronizedvoidmethod();synchronizedpublicvoidmethod();();();();

但要注意 synchronized不能放在方法返回類型的後面 如下面的代碼是錯誤的

publicvoidsynchronizedmethod();();

synchronized關鍵字只能用來同步方法 不能用來同步類變數 如下面的代碼也是錯誤的

publicsynchronizedintn= ;publicstaticsynchronizedintn= ;

雖然使用synchronized關鍵字同步方法是最安全的同步方式 但大量使用synchronized關鍵字會造成不必要的資源消耗以及性能損失 雖然從表面上看synchronized鎖定的是一個方法 但實際上synchronized鎖定的是一個類 也就是說 如果在非靜態方法method 和method 定義時都使用了synchronized 在method 未執行完之前 method 是不能執行的 靜態方法和非靜態方法的情況類似 但靜態和非靜態方法不會互相影響 看看如下的代碼

packagetest;publicclassMyThread extendsThread{publicStringmethodName;publicstaticvoidmethod(Strings){System out println(s);while(true);}publicsynchronizedvoidmethod (){method( 非靜態的method 方法 );}publicsynchronizedvoidmethod (){method( 非靜態的method 方法 );} (){method( 靜態的method 方法 );} (){method( 靜態的method 方法 );}publicvoidrun(){try{getClass() getMethod(methodName) invoke(this);}catch(Exceptione){}}publicstaticvoidmain(String[]args)throwsException{MyThread myThread =newMyThread ();for(inti= ;i<= ;i++){thodName= method +String valueOf(i);newThread(myThread ) start();sleep( );}}}

運行結果如下

非靜態的method 方法靜態的method 方法

lishixin/Article/program/Java/gj/201311/27526

C. java中線程同步的幾種方法

線程同步主要有以下種方法(示例中是實現計數的功能):

1、同步方法,即使用synchronized關鍵字修飾方法,例如:

publicsynchronizedvoidadd(intc){...}

2、同步代碼塊,即有synchronized關鍵字修飾的語句塊,例如:

publicvoidaddAndGet(intc){
synchronized(this){
count+=c;
}
}

3、使用特殊域變數(volatile)實現線程同步,該方法不能保證絕對的同步。

例如:privatevolatileintcount=0;

4、使用鎖實現線程同步,例如:

privateLocklock=newReentrantLock();
publicvoidadd(intc){
lock.lock();//上鎖
try{
count+=c;
}finally{
lock.unlock();//解鎖
}
}

5、使用原子變數實現線程同步,在java的util.concurrent.atomic包中提供了創建了原子類型變數的工具類,例如:

privateAtomicIntegercount=newAtomicInteger(1);
publicvoidadd(intc){
count.addAndGet(c);
}

6、使用局部變數實現線程同步,如果使用ThreadLocal管理變數,則每一個使用該變數的線程都獲得該變數的副本, 副本之間相互獨立,這樣每一個線程都可以隨意修改自己的變數副本,而不會對其他線程產生影響。

ThreadLocal 類的常用方法

new ThreadLocal<T>() : 創建一個線程本地變數

get() : 返回此線程局部變數的當前線程副本中的值

initialValue() : 返回此線程局部變數的當前線程的"初始值"

set(T value) : 將此線程局部變數的當前線程副本中的值設置為value

示例代碼:

privatestaticThreadLocal<Integer>count=newThreadLocal<Integer>(){
@Override
protectedIntegerinitialValue(){
return1;
}
};

publicvoidadd(intc){
count.set(count.get()+c);
}

7、使用阻塞隊列實現,例如LinkedBlockingQueue,具體使用可網路LinkedBlockingQueue的用法或查看java文檔。

D. Java實現線程同步的幾種方式

java中多線程的實現方法有兩種:1.直接繼承thread類;2.實現runnable介面;同步的實現方法有五種:1.同步方法;2.同步代碼塊;3.使用特殊域變數(volatile)實現線程同步;4.使用重入鎖實現線程同步;5.使用局部變數實現線程同步 。
其中多線程實現過程中需注意重寫或者覆蓋run()方法,而對於同步的實現方法中使用較常使用的是利用synchronized編寫同步方法和代碼塊。

E. java 實現線程同步的方式有哪些

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

F. Java類的實例化順序是什麼樣的Java線程同步的方式有哪些

引言:java是在1990年初 ,被詹姆斯•高斯林等人開發的一門面向對象的編程語言。起初,java被稱為0ak,來經過發展0ak改名為java,與1995年的五月份正式向大家發布。

一、java類的實例化順序

java的實例化順序在繼承沒有的情況

單獨一個類的場景下,初始化順序為依次為靜態數據,繼承的基類的構造函數,成員變數,被調用的構造函數。

其中靜態數據只會初始化一次。(靜態數據包括靜態代碼塊和靜態變數,每個類的靜態數據只會初始化一次)

在繼承的情況下

添加兩個基類,讓繼承父親,父親繼承祖父。

繼承的情況就比較復雜了。由繼承了基類,還將往上回溯,遞歸地調用基類的無參構造方法。

在我們的例子中,在初始化靜態數據後,會先往上追溯,調用父的默認構造方法,此時再往上追溯到爺爺的默認構造方法。


無論是java還是什麼別的東西他都體現了現代社會與信息技術的不斷發展,人們在進行進行技術開發時也有了越來越多的方法。程序類的工作也有了更為快捷的方法,這為信息技術的發展也提供了更好的發展方法

G. Java 線程同步幾種方式

(1)同步方法:
即有synchronized關鍵字修飾的方法。 由於java的每個對象都有一個內置鎖,當用此關鍵字修飾方法時,內置鎖會保護整個方法。在調用該方法前,需要獲得內置鎖,否則就處於阻塞狀態。
(2)同步代碼塊
即有synchronized關鍵字修飾的語句塊。被該關鍵字修飾的語句塊會自動被加上內置鎖,從而實現同步
(3)使用特殊域變數(Volatile)實現線程同步
a.volatile關鍵字為域變數的訪問提供了一種免鎖機制
b.使用volatile修飾域相當於告訴虛擬機該域可能會被其他線程更新
c.因此每次使用該域就要重新計算,而不是使用寄存器中的值
d.volatile不會提供任何原子操作,它也不能用來修飾final類型的變數
(4)使用重入鎖實現線程同步
在JavaSE5.0中新增了一個java.util.concurrent包來支持同步。ReentrantLock類是可重入、互斥、實現了Lock介面的鎖, 它與使用synchronized方法和快具有相同的基本行為和語義,並且擴展了其能力。
(5)使用局部變數實現線程同步

閱讀全文

與java同步方法實現相關的資料

熱點內容
常微分第三版答案pdf 瀏覽:262
安卓機qq怎麼開懸浮窗 瀏覽:61
備孕三年了怎麼緩解壓力大 瀏覽:741
登錄阿里雲伺服器黑屏 瀏覽:334
匿名元組Python 瀏覽:723
華為運動健康存儲的文件夾 瀏覽:520
cad正多邊形命令 瀏覽:461
壓縮比150能加97油嗎 瀏覽:397
linux新建群在哪個文件夾 瀏覽:794
韻達快運app在哪裡簽收 瀏覽:336
阿里雲伺服器如何綁定備案域名 瀏覽:273
單片機用什麼鍵盤好 瀏覽:25
android動畫面試 瀏覽:309
pdf無法刪除 瀏覽:90
ftp刪除文件java 瀏覽:89
裂變棋牌源碼 瀏覽:87
邀月命令江別鶴退婚 瀏覽:656
春秋app在哪裡查詢 瀏覽:136
用linux設計 瀏覽:747
安卓intent什麼意思 瀏覽:946