線程同步主要有以下種方法(示例中是實(shí)現(xiàn)計(jì)數(shù)的功能):

10年積累的成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站制作后付款的網(wǎng)站建設(shè)流程,更有丘北免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
1、同步方法,即使用synchronized關(guān)鍵字修飾方法,例如:
public?synchronized?void?add(int?c){...}
2、同步代碼塊,即有synchronized關(guān)鍵字修飾的語(yǔ)句塊,例如:
public?void?addAndGet(int?c){
synchronized(this){
count?+=?c;
}
}
3、使用特殊域變量(volatile)實(shí)現(xiàn)線程同步,該方法不能保證絕對(duì)的同步。
例如:private?volatile?int?count?=?0;
4、使用鎖實(shí)現(xiàn)線程同步,例如:
private?Lock?lock?=?new?ReentrantLock();
public?void?add(int?c)?{??
lock.lock();//上鎖??
try{??
count?+=?c;??
}finally{??
lock.unlock();//解鎖??
}??
}
5、使用原子變量實(shí)現(xiàn)線程同步,在java的util.concurrent.atomic包中提供了創(chuàng)建了原子類型變量的工具類,例如:
private?AtomicInteger?count=?new?AtomicInteger(1);
public?void?add(int?c)?{
count.addAndGet(c);
}
6、使用局部變量實(shí)現(xiàn)線程同步,如果使用ThreadLocal管理變量,則每一個(gè)使用該變量的線程都獲得該變量的副本, 副本之間相互獨(dú)立,這樣每一個(gè)線程都可以隨意修改自己的變量副本,而不會(huì)對(duì)其他線程產(chǎn)生影響。
ThreadLocal 類的常用方法
new ThreadLocalT() : 創(chuàng)建一個(gè)線程本地變量
get() : 返回此線程局部變量的當(dāng)前線程副本中的值
initialValue() : 返回此線程局部變量的當(dāng)前線程的"初始值"
set(T value) : 將此線程局部變量的當(dāng)前線程副本中的值設(shè)置為value
示例代碼:
private?static?ThreadLocalInteger?count=?new?ThreadLocalInteger(){
@Override
protected?Integer?initialValue(){?
return?1;
}
};????????????
public?void?add(int?c){
count.set(count.get()?+?c);
}
7、使用阻塞隊(duì)列實(shí)現(xiàn),例如LinkedBlockingQueue,具體使用可百度LinkedBlockingQueue的用法或查看java文檔。
java中多線程的實(shí)現(xiàn)方法有兩種:1.直接繼承thread類;2.實(shí)現(xiàn)runnable接口;同步的實(shí)現(xiàn)方法有五種:1.同步方法;2.同步代碼塊;3.使用特殊域變量(volatile)實(shí)現(xiàn)線程同步;4.使用重入鎖實(shí)現(xiàn)線程同步;5.使用局部變量實(shí)現(xiàn)線程同步 。
其中多線程實(shí)現(xiàn)過(guò)程中需注意重寫或者覆蓋run()方法,而對(duì)于同步的實(shí)現(xiàn)方法中使用較常使用的是利用synchronized編寫同步方法和代碼塊。
謝謝采納!!
引言:java是在1990年初 ,被詹姆斯?高斯林等人開發(fā)的一門面向?qū)ο蟮木幊陶Z(yǔ)言。起初,java被稱為0ak,來(lái)經(jīng)過(guò)發(fā)展0ak改名為java,與1995年的五月份正式向大家發(fā)布。
一、java類的實(shí)例化順序
java的實(shí)例化順序在繼承沒有的情況
單獨(dú)一個(gè)類的場(chǎng)景下,初始化順序?yàn)橐来螢殪o態(tài)數(shù)據(jù),繼承的基類的構(gòu)造函數(shù),成員變量,被調(diào)用的構(gòu)造函數(shù)。
其中靜態(tài)數(shù)據(jù)只會(huì)初始化一次。(靜態(tài)數(shù)據(jù)包括靜態(tài)代碼塊和靜態(tài)變量,每個(gè)類的靜態(tài)數(shù)據(jù)只會(huì)初始化一次)
在繼承的情況下
添加兩個(gè)基類,讓繼承父親,父親繼承祖父。
繼承的情況就比較復(fù)雜了。由繼承了基類,還將往上回溯,遞歸地調(diào)用基類的無(wú)參構(gòu)造方法。
在我們的例子中,在初始化靜態(tài)數(shù)據(jù)后,會(huì)先往上追溯,調(diào)用父的默認(rèn)構(gòu)造方法,此時(shí)再往上追溯到爺爺?shù)哪J(rèn)構(gòu)造方法。
二、信息技術(shù)的不斷發(fā)展
java也體現(xiàn)了現(xiàn)代社會(huì)下信息技術(shù)的不斷發(fā)展,科技水平的不斷進(jìn)步,人們的工作也越來(lái)越便利,日常生活也越來(lái)越方便,越來(lái)越多的工具被人們所開發(fā)應(yīng)用 。科技的發(fā)展也要求我們掌握更多的知識(shí),在探索的過(guò)程中,我們需要明白更方便的方法使用更便捷的方法來(lái)取得成就,我的方法會(huì)讓過(guò)程事半功倍。科技的發(fā)展也要求我們掌握越來(lái)越多的知識(shí),我們可以通過(guò)學(xué)習(xí)來(lái)獲得更多的知識(shí),來(lái)幫助我們?cè)谝院蟮墓ぷ魃睿嘈┘寄芸偸怯泻锰幍?。
無(wú)論是java還是什么別的東西他都體現(xiàn)了現(xiàn)代社會(huì)與信息技術(shù)的不斷發(fā)展,人們?cè)谶M(jìn)行進(jìn)行技術(shù)開發(fā)時(shí)也有了越來(lái)越多的方法。程序類的工作也有了更為快捷的方法,這為信息技術(shù)的發(fā)展也提供了更好的發(fā)展方法
(1)同步方法:
即有synchronized關(guān)鍵字修飾的方法。 由于java的每個(gè)對(duì)象都有一個(gè)內(nèi)置鎖,當(dāng)用此關(guān)鍵字修飾方法時(shí),內(nèi)置鎖會(huì)保護(hù)整個(gè)方法。在調(diào)用該方法前,需要獲得內(nèi)置鎖,否則就處于阻塞狀態(tài)。
(2)同步代碼塊
即有synchronized關(guān)鍵字修飾的語(yǔ)句塊。被該關(guān)鍵字修飾的語(yǔ)句塊會(huì)自動(dòng)被加上內(nèi)置鎖,從而實(shí)現(xiàn)同步
(3)使用特殊域變量(Volatile)實(shí)現(xiàn)線程同步
a.volatile關(guān)鍵字為域變量的訪問提供了一種免鎖機(jī)制
b.使用volatile修飾域相當(dāng)于告訴虛擬機(jī)該域可能會(huì)被其他線程更新
c.因此每次使用該域就要重新計(jì)算,而不是使用寄存器中的值
d.volatile不會(huì)提供任何原子操作,它也不能用來(lái)修飾final類型的變量
(4)使用重入鎖實(shí)現(xiàn)線程同步
在JavaSE5.0中新增了一個(gè)java.util.concurrent包來(lái)支持同步。ReentrantLock類是可重入、互斥、實(shí)現(xiàn)了Lock接口的鎖, 它與使用synchronized方法和快具有相同的基本行為和語(yǔ)義,并且擴(kuò)展了其能力。
(5)使用局部變量實(shí)現(xiàn)線程同步
1.同步方法 即有synchronized關(guān)鍵字修飾的方法。 由于java的每個(gè)對(duì)象都有一個(gè)內(nèi)置鎖,當(dāng)用此關(guān)鍵字修飾方法時(shí), 內(nèi)置鎖會(huì)保護(hù)整個(gè)方法。在調(diào)用該方法前,需要獲得內(nèi)置鎖,否則就處于阻塞狀態(tài)。 代碼如: public synchronized void save(){} 注: synchronized關(guān)鍵字也可以修飾靜態(tài)方法,此時(shí)如果調(diào)用該靜態(tài)方法,將會(huì)鎖住整個(gè)類 2.同步代碼塊 即有synchronized關(guān)鍵字修飾的語(yǔ)句塊。 被該關(guān)鍵字修飾的語(yǔ)句塊會(huì)自動(dòng)被加上內(nèi)置鎖,從而實(shí)現(xiàn)同步 代碼如: synchronized(object){ } 注:同步是一種高開銷的操作,因此應(yīng)該盡量減少同步的內(nèi)容。 通常沒有必要同步整個(gè)方法,使用synchronized代碼塊同步關(guān)鍵代碼即可。 代碼實(shí)例: 復(fù)制代碼package com.xhj.thread; /** * 線程同步的運(yùn)用 * * @author XIEHEJUN * */ public class SynchronizedThread { class Bank { private int account = 100; public int getAccount() { return account; } /** * 用同步方法實(shí)現(xiàn) * * @param money */ public synchronized void save(int money) { account += money; } /** * 用同步代碼塊實(shí)現(xiàn) * * @param money */ public void save1(int money) { synchronized (this) { account += money; } } } class NewThread implements Runnable { private Bank bank; public NewThread(Bank bank) { this.bank = bank; } @Override public void run() { for (int i = 0; i 10; i++) { // bank.save1(10); bank.save(10); System.out.println(i + "賬戶余額為:" + bank.getAccount()); } } } /** * 建立線程,調(diào)用內(nèi)部類 */ public void useThread() { Bank bank = new Bank(); NewThread new_thread = new NewThread(bank); System.out.println("線程1"); Thread thread1 = new Thread(new_thread); thread1.start(); System.out.println("線程2"); Thread thread2 = new Thread(new_thread); thread2.start(); } public static void main(String[] args) { SynchronizedThread st = new SynchronizedThread(); st.useThread(); } }復(fù)制代碼 3.使用特殊域變量(volatile)實(shí)現(xiàn)線程同步 a.volatile關(guān)鍵字為域變量的訪問提供了一種免鎖機(jī)制, b.使用volatile修飾域相當(dāng)于告訴虛擬機(jī)該域可能會(huì)被其他線程更新, c.因此每次使用該域就要重新計(jì)算,而不是使用寄存器中的值 d.volatile不會(huì)提供任何原子操作,它也不能用來(lái)修飾final類型的變量 例如: 在上面的例子當(dāng)中,只需在account前面加上volatile修飾,即可實(shí)現(xiàn)線程同步。 代碼實(shí)例: 復(fù)制代碼 //只給出要修改的代碼,其余代碼與上同 class Bank { //需要同步的變量加上volatile private volatile int account = 100; public int getAccount() { return account; } //這里不再需要synchronized public void save(int money) { account += money; } }復(fù)制代碼 注:多線程中的非同步問題主要出現(xiàn)在對(duì)域的讀寫上,如果讓域自身避免這個(gè)問題,則就不需要修改操作該域的方法。 用final域,有鎖保護(hù)的域和volatile域可以避免非同步的問題。 4.使用重入鎖實(shí)現(xiàn)線程同步 在JavaSE5.0中新增了一個(gè)java.util.concurrent包來(lái)支持同步。 ReentrantLock類是可重入、互斥、實(shí)現(xiàn)了Lock接口的鎖, 它與使用synchronized方法和快具有相同的基本行為和語(yǔ)義,并且擴(kuò)展了其能力 ReenreantLock類的常用方法有: ReentrantLock() : 創(chuàng)建一個(gè)ReentrantLock實(shí)例 lock() : 獲得鎖 unlock() : 釋放鎖 注:ReentrantLock()還有一個(gè)可以創(chuàng)建公平鎖的構(gòu)造方法,但由于能大幅度降低程序運(yùn)行效率,不推薦使用 例如: 在上面例子的基礎(chǔ)上,改寫后的代碼為: 代碼實(shí)例: 復(fù)制代碼//只給出要修改的代碼,其余代碼與上同 class Bank { private int account = 100; //需要聲明這個(gè)鎖 private Lock lock = new ReentrantLock(); public int getAccount() { return account; } //這里不再需要synchronized public void save(int money) { lock.lock(); try{ account += money; }finally{ lock.unlock(); } } }復(fù)制代碼 注:關(guān)于Lock對(duì)象和synchronized關(guān)鍵字的選擇: a.最好兩個(gè)都不用,使用一種java.util.concurrent包提供的機(jī)制, 能夠幫助用戶處理所有與鎖相關(guān)的代碼。 b.如果synchronized關(guān)鍵字能滿足用戶的需求,就用synchronized,因?yàn)樗芎?jiǎn)化代碼 c.如果需要更高級(jí)的功能,就用ReentrantLock類,此時(shí)要注意及時(shí)釋放鎖,否則會(huì)出現(xiàn)死鎖,通常在finally代碼釋放鎖 5.使用局部變量實(shí)現(xiàn)線程同步 如果使用ThreadLocal管理變量,則每一個(gè)使用該變量的線程都獲得該變量的副本, 副本之間相互獨(dú)立,這樣每一個(gè)線程都可以隨意修改自己的變量副本,而不會(huì)對(duì)其他線程產(chǎn)生影響。 ThreadLocal 類的常用方法 ThreadLocal() : 創(chuàng)建一個(gè)線程本地變量 get() : 返回此線程局部變量的當(dāng)前線程副本中的值 initialValue() : 返回此線程局部變量的當(dāng)前線程的"初始值" set(T value) : 將此線程局部變量的當(dāng)前線程副本中的值設(shè)置為value 例如: 在上面例子基礎(chǔ)上,修改后的代碼為: 代碼實(shí)例: 復(fù)制代碼//只改Bank類,其余代碼與上同 public class Bank{ //使用ThreadLocal類管理共享變量account private static ThreadLocalInteger account = new ThreadLocalInteger(){ @Override protected Integer initialValue(){ return 100; } }; public void save(int money){ account.set(account.get()+money); } public int getAccount(){ return account.get(); } }復(fù)制代碼 注:ThreadLocal與同步機(jī)制 a.ThreadLocal與同步機(jī)制都是為了解決多線程中相同變量的訪問沖突問題。 b.前者采用以"空間換時(shí)間"的方法,后者采用以"時(shí)間換空間"的方式。
分享名稱:包含java代碼塊對(duì)同步方式的詞條
轉(zhuǎn)載源于:http://chinadenli.net/article5/dsedeii.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供面包屑導(dǎo)航、定制開發(fā)、網(wǎng)站營(yíng)銷、品牌網(wǎng)站建設(shè)、企業(yè)建站、標(biāo)簽優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)