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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

Java培训教程之使用Lock取代synchronized

發(fā)布時間:2024/9/30 java 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java培训教程之使用Lock取代synchronized 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在多線程中,1.5版本之前,我們都使用同步代碼塊或者同步方法來解決線程安全問題

比如:

同步代碼塊

synchronized(鎖對象){

功能代碼;

}

同步方法

public synchronized void test(){

功能代碼;

}

在1.5版本,在java的工具類包中,java.util.concurrent.locks 中,推出了最新的

解決線程安全的方法,就是Lock+Condition的方式,

那這兩種方式之間的關(guān)系和區(qū)別是什么呢?

加入對于線程常見的生產(chǎn)者消費(fèi)者模式,我們使用兩種方式實(shí)現(xiàn),來看看他們的區(qū)別:

第一種,使用synchronized

我們完成一個男人掙錢女人花的例子

需求是如果沒錢,男人線程掙一次錢,等待,然后喚醒女人去花錢,花完錢,等待,喚醒

男人去掙錢,一直循環(huán)這個過程,將男人線程看做生產(chǎn)線程,女人線程看做消費(fèi)線程。

代碼如下:

//首先完成共享數(shù)據(jù)

class Person{

String name;

boolean isMoney=true;

//掙錢

public void zhengQian(){

synchronized(this){

while(!isMoney){

try{wait();}catch(Exception e){}

}

name=“男人”;

System.out.println(Thread.currentThread().getName()+name+"—掙錢—");

isMoney=!isMoney;

notifyAll();//叫醒所有

}

}

//花錢

public void huaQian(){

synchronized(this){

while(isMoney){

try{wait();}catch(Exception e){}

}

name=“women。。。。人”;

System.out.println(Thread.currentThread().getName()+name+"—花=========錢—");

isMoney=!isMoney;

notifyAll();//叫醒所有

}

}

}

//輸入線程

class In implements Runnable{

Person p=null;

In(Person p){

this.p=p;

}

public void run(){

while(true){

p.zhengQian();

}

}

}

//輸出線程

class Out implements Runnable{

Person p=null;

Out(Person p){

this.p=p;

}

public void run(){

while(true){

p.huaQian();

}

}

}

從代碼中可以看出,對于同步代碼塊或者同步方法來說,都是以鎖對象this來控制其鎖定的代碼的。

api中也告訴我們:

Lock 實(shí)現(xiàn)提供了比使用 synchronized 方法和語句可獲得的更廣泛的鎖定操作。此實(shí)現(xiàn)允許更靈活的結(jié)構(gòu),可以具有差別很大的屬性,可以支持多個相關(guān)的 Condition 對象。

那使用Lock+Condition怎么來實(shí)現(xiàn)呢?

代碼如下:

import java.util.concurrent.locks.*;

class Person{

String name;

boolean isMoney=true;

Lock lock=new ReentrantLock();

Condition in=lock.newCondition();

Condition out=lock.newCondition();

//掙錢

public void zhengQian(){

lock.lock();

try{

while(!isMoney){

try{in.wait();}catch(Exception e){}

}

name=“男人”;

System.out.println(Thread.currentThread().getName()+name+"—掙錢—");

isMoney=!isMoney;

out.signal();//叫醒對方

}finally{

lock.unlock();

}

}

//花錢

public void huaQian(){

lock.lock();

try{

while(!isMoney){

try{out.wait();}catch(Exception e){}

}

name=“women。。。。人”;

System.out.println(Thread.currentThread().getName()+name+"—花=========錢—");

isMoney=!isMoney;

in.signal();//叫醒對方

}finally{

lock.unlock();

}

}

}

對比發(fā)現(xiàn),Lock+Condition的方式是使用Condition對象來具體操作現(xiàn)場的等待和喚醒的,

也就是對于生產(chǎn)線程有專屬的生成線程的Condition對象,對消費(fèi)線程有專屬的消費(fèi)線程的Condition

對象,當(dāng)?shù)却蛘邌拘褧r可以精確的控制是哪方線程,同步代碼塊或者同步方法在喚醒時,不能精確的

喚醒對方,所以只能喚醒全部,這時候增加了線程的判斷次數(shù),明顯,Lock+Condition是優(yōu)于synchronized的方式的

接下來我們分析下Lock和Condition的關(guān)系

Lock的子類對象是來取代synchronized的,也就是鎖,Condition只是鎖的操作對象

取代的是以前的鎖對象,都擁有等待和喚醒的方法,雖然名字不同,Condition主要是對鎖的操作對象

進(jìn)行分類,如下圖:

上圖中,一個Lock對象,創(chuàng)建出來三個Condition對象 x,y,z

也就是以后執(zhí)行這個鎖的線程將會被分成三類線程,比如如果執(zhí)行x.await(),執(zhí)行這段代碼的

三個綠色線程將會進(jìn)入等待狀態(tài),再比如z中三個紅色線程都處于等待狀態(tài),如果執(zhí)行z.signal(),將會喚醒執(zhí)行z的三個紅色線程中的某一個,這樣代碼就可以正常運(yùn)行了。

藍(lán)色線兩側(cè)分別表示兩個Lock的子類對象,每一個lock的Condition之間可以互相操作,對于兩個

鎖之間的Condition,比如,x和Q,就沒有直接的關(guān)系了

好了,這篇文章主要說明下Lock+Condition方式來取代synchronized,希望對大家有所幫助。

本文來自千鋒教育,轉(zhuǎn)載請注明出處。

總結(jié)

以上是生活随笔為你收集整理的Java培训教程之使用Lock取代synchronized的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。