java的同步代碼 java同步代碼塊

java中的同步代碼塊,為什么隨便放個對象,就可以鎖住代碼塊呢?什么原理?

synchronized(這里的對象你看成一道門) {

成都創(chuàng)新互聯(lián)總部坐落于成都市區(qū),致力網(wǎng)站建設(shè)服務(wù)有網(wǎng)站建設(shè)、成都網(wǎng)站制作、網(wǎng)絡(luò)營銷策劃、網(wǎng)頁設(shè)計、網(wǎng)站維護(hù)、公眾號搭建、微信小程序定制開發(fā)、軟件開發(fā)等為企業(yè)提供一整套的信息化建設(shè)解決方案。創(chuàng)造真正意義上的網(wǎng)站建設(shè),為互聯(lián)網(wǎng)品牌在互動行銷領(lǐng)域創(chuàng)造價值而不懈努力!

這里是一個人進(jìn)來了,把門反鎖了

需要同步操作的代碼

這里是里面的人事情做完了,出去了,門開著其他人可以進(jìn)了

}

至于怎么鎖的,這是java和jvm的規(guī)定和實現(xiàn)細(xì)節(jié),作為普通程序員沒必要深入那么多。

淺談Java多線程的同步問題

多線程的同步依靠的是對象鎖機(jī)制 synchronized關(guān)鍵字的背后就是利用了封鎖來實現(xiàn)對共享資源的互斥訪問

下面以一個簡單的實例來進(jìn)行對比分析 實例要完成的工作非常簡單 就是創(chuàng)建 個線程 每個線程都打印從 到 這 個數(shù)字 我們希望線程之間不會出現(xiàn)交叉亂序打印 而是順序地打印

先來看第一段代碼 這里我們在run()方法中加入了synchronized關(guān)鍵字 希望能對run方法進(jìn)行互斥訪問 但結(jié)果并不如我們希望那樣 這是因為這里synchronized鎖住的是this對象 即當(dāng)前運(yùn)行線程對象本身 代碼中創(chuàng)建了 個線程 而每個線程都持有this對象的對象鎖 這不能實現(xiàn)線程的同步

代碼??? package vista;??? class MyThread implements java lang Runnable {???? private int threadId;

public MyThread(int id) {????? this threadId = id;???? }

@Override???? public synchronized void run() {????? for (int i = ; i ; ++i) {?????? System out println( Thread ID: + this threadId + : + i);????? }???? }??? }

public class ThreadDemo {???? /**????? * @param args????? * @throws InterruptedException????? */???? public static void main(String[] args) throws InterruptedException {????? for (int i = ; i ; ++i) {?????? new Thread(new MyThread(i)) start();?????? Thread sleep( );????? }???? }??? }

從上述代碼段可以得知 要想實現(xiàn)線程的同步 則這些線程必須去競爭一個唯一的共享的對象鎖

基于這種思想 我們將第一段代碼修改如下所示 在創(chuàng)建啟動線程之前 先創(chuàng)建一個線程之間競爭使用的Object對象 然后將這個Object對象的引用傳遞給每一個線程對象的lock成員變量 這樣一來 每個線程的lock成員都指向同一個Object對象 我們在run方法中 對lock對象使用synchronzied塊進(jìn)行局部封鎖 這樣就可以讓線程去競爭這個唯一的共享的對象鎖 從而實現(xiàn)同步

代碼??? package vista;

class MyThread implements java lang Runnable {???? private int threadId;???? private Object lock;

public MyThread(int id Object obj) {????? this threadId = id;????? this lock = obj;???? }

@Override???? public void run() {????? synchronized (lock) {?????? for (int i = ; i ; ++i) {??????? System out println( Thread ID: + this threadId + : + i);?????? }????? }???? }??? }

public class ThreadDemo {???? /**????? * @param args????? * @throws InterruptedException????? */???? public static void main(String[] args) throws InterruptedException {????? Object obj = new Object();????? for (int i = ; i ; ++i) {?????? new Thread(new MyThread(i obj)) start();?????? Thread sleep( );????? }???? }??? }

從第二段代碼可知 同步的關(guān)鍵是多個線程對象競爭同一個共享資源即可 上面的代碼中是通過外部創(chuàng)建共享資源 然后傳遞到線程中來實現(xiàn) 我們也可以利用類成員變量被所有類的實例所共享這一特性 因此可以將lock用靜態(tài)成員對象來實現(xiàn) 代碼如下所示

代碼??? package vista;

class MyThread implements java lang Runnable {???? private int threadId;???? private static Object lock = new Object();

public MyThread(int id) {????? this threadId = id;???? }

@Override???? public void run() {????? synchronized (lock) {?????? for (int i = ; i ; ++i) {??????? System out println( Thread ID: + this threadId + : + i);?????? }????? }???? }??? }

public class ThreadDemo {???? /**????? * @param args????? * @throws InterruptedException????? */???? public static void main(String[] args) throws InterruptedException {????? for (int i = ; i ; ++i) {?????? new Thread(new MyThread(i)) start();?????? Thread sleep( );????? }???? }??? }

再來看第一段代碼 實例方法中加入sychronized關(guān)鍵字封鎖的是this對象本身 而在靜態(tài)方法中加入sychronized關(guān)鍵字封鎖的就是類本身 靜態(tài)方法是所有類實例對象所共享的 因此線程對象在訪問此靜態(tài)方法時是互斥訪問的 從而可以實現(xiàn)線程的同步 代碼如下所示

代碼??? package vista;

class MyThread implements java lang Runnable {???? private int threadId;

public MyThread(int id) {????? this threadId = id;???? }

@Override???? public void run() {????? taskHandler(this threadId);???? }

private static synchronized void taskHandler(int threadId) {????? for (int i = ; i ; ++i) {?????? System out println( Thread ID: + threadId + : + i);????? }???? }??? }

lishixinzhi/Article/program/Java/gj/201311/27441

java中實現(xiàn)同步的方法有哪兩種?

Java的同步可以用synchronized關(guān)鍵字來實現(xiàn)。\x0d\x0a \x0d\x0asychronized可以同步代碼,需要綁定一個對象,如synchronized(obj){}\x0d\x0a也可以同步一個方法,是對方法進(jìn)行線程同步。如public void synchronized methodA(){}

幫忙解讀Java 同步代碼

public static Object lock=new Object(); // 創(chuàng)建一個對象, 他是一個靜態(tài)變量。

public static DataBaseDS getInstance(){

// 這里是判斷這個對象是否已經(jīng)存在

if(sybDB==null){

// 這是一個同步鎖, 也就是對于該對象的操作,被強(qiáng)制為同步的,同步也就是說,一次只能有一個用戶去操作它,其余的請求都需要排隊,就像我們在食堂打飯一樣,要一個一個打

synchronized (lock) {

// 如果這個對象為空就創(chuàng)建一個

if(sybDB==null){

sybDB=new DataBaseDS();

}

}

}// 將結(jié)果返回

return sybDB;

}

java中線程同步的幾種方法

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

1、同步方法,即使用synchronized關(guān)鍵字修飾方法,例如:

public?synchronized?void?add(int?c){...}

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

public?void?addAndGet(int?c){

synchronized(this){

count?+=?c;

}

}

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

例如:private?volatile?int?count?=?0;

4、使用鎖實現(xiàn)線程同步,例如:

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

public?void?add(int?c)?{??

lock.lock();//上鎖??

try{??

count?+=?c;??

}finally{??

lock.unlock();//解鎖??

}??

}

5、使用原子變量實現(xiàn)線程同步,在java的util.concurrent.atomic包中提供了創(chuàng)建了原子類型變量的工具類,例如:

private?AtomicInteger?count=?new?AtomicInteger(1);

public?void?add(int?c)?{

count.addAndGet(c);

}

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

ThreadLocal 類的常用方法

new ThreadLocalT() : 創(chuàng)建一個線程本地變量

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、使用阻塞隊列實現(xiàn),例如LinkedBlockingQueue,具體使用可百度LinkedBlockingQueue的用法或查看java文檔。

java中同步有幾種方式啊

1。同步代碼塊:

synchronized(同一個數(shù)據(jù)){} 同一個數(shù)據(jù):就是N條線程同時訪問一個數(shù)據(jù)。

2。

同步方法:

public synchronized 數(shù)據(jù)返回類型 方法名(){}

是使用 synchronized 來修飾某個方法,則該方法稱為同步方法。對于同步方法而言,無需顯示指定同步監(jiān)視器,同步方法的同步監(jiān)視器是

this

也就是該對象的本身(這里指的對象本身有點含糊,其實就是調(diào)用該同步方法的對象)通過使用同步方法,可非常方便的將某類變成線程安全的類,具有如下特征:

1,該類的對象可以被多個線程安全的訪問。

2,每個線程調(diào)用該對象的任意方法之后,都將得到正確的結(jié)果。

3,每個線程調(diào)用該對象的任意方法之后,該對象狀態(tài)依然保持合理狀態(tài)。

注:synchronized關(guān)鍵字可以修飾方法,也可以修飾代碼塊,但不能修飾構(gòu)造器,屬性等。

實現(xiàn)同步機(jī)制注意以下幾點: 安全性高,性能低,在多線程用。性能高,安全性低,在單線程用。

1,不要對線程安全類的所有方法都進(jìn)行同步,只對那些會改變共享資源方法的進(jìn)行同步。

2,如果可變類有兩種運(yùn)行環(huán)境,當(dāng)線程環(huán)境和多線程環(huán)境則應(yīng)該為該可變類提供兩種版本:線程安全版本和線程不安全版本(沒有同步方法和同步塊)。在單線程中環(huán)境中,使用線程不安全版本以保證性能,在多線程中使用線程安全版本.

線程通訊:

為什么要使用線程通訊?

當(dāng)

使用synchronized

來修飾某個共享資源時(分同步代碼塊和同步方法兩種情況),當(dāng)某個線程獲得共享資源的鎖后就可以執(zhí)行相應(yīng)的代碼段,直到該線程運(yùn)行完該代碼段后才釋放對該

共享資源的鎖,讓其他線程有機(jī)會執(zhí)行對該共享資源的修改。當(dāng)某個線程占有某個共享資源的鎖時,如果另外一個線程也想獲得這把鎖運(yùn)行就需要使用wait()

和notify()/notifyAll()方法來進(jìn)行線程通訊了。

Java.lang.object 里的三個方法wait() notify() notifyAll()

wait方法導(dǎo)致當(dāng)前線程等待,直到其他線程調(diào)用同步監(jiān)視器的notify方法或notifyAll方法來喚醒該線程。

wait(mills)方法

都是等待指定時間后自動蘇醒,調(diào)用wait方法的當(dāng)前線程會釋放該同步監(jiān)視器的鎖定,可以不用notify或notifyAll方法把它喚醒。

notify()

喚醒在同步監(jiān)視器上等待的單個線程,如果所有線程都在同步監(jiān)視器上等待,則會選擇喚醒其中一個線程,選擇是任意性的,只有當(dāng)前線程放棄對該同步監(jiān)視器的鎖定后,也就是使用wait方法后,才可以執(zhí)行被喚醒的線程。

notifyAll()方法

喚醒在同步監(jiān)視器上等待的所有的線程。只用當(dāng)前線程放棄對該同步監(jiān)視器的鎖定后,才可以執(zhí)行被喚醒的線程

網(wǎng)頁標(biāo)題:java的同步代碼 java同步代碼塊
文章分享:http://muchs.cn/article0/hjsdio.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供、網(wǎng)站策劃、外貿(mào)網(wǎng)站建設(shè)標(biāo)簽優(yōu)化、電子商務(wù)、網(wǎng)站改版

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都做網(wǎng)站