十年網(wǎng)站開發(fā)經(jīng)驗(yàn) + 多家企業(yè)客戶 + 靠譜的建站團(tuán)隊
量身定制 + 運(yùn)營維護(hù)+專業(yè)推廣+無憂售后,網(wǎng)站問題一站解決
本篇文章給大家分享的是有關(guān)如何在Java中使用Condition控制線程通信,小編覺得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司,提供網(wǎng)站建設(shè)、成都做網(wǎng)站,網(wǎng)頁設(shè)計,建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);可快速的進(jìn)行網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,是專業(yè)的做網(wǎng)站團(tuán)隊,希望更多企業(yè)前來合作!
一 點(diǎn)睛
當(dāng)使用Lock對象來保證同步時,Java提供了一個Condition類來保持協(xié)調(diào),使用Condition可以讓那些已經(jīng)得到Lock對象、卻無法繼續(xù)執(zhí)行的線程釋放Lock對象,Condtion對象也可以喚醒其他處于等待的線程。
Condition 將同步監(jiān)視鎖方法(wait、notify 和 notifyAll)分解成截然不同的對象,以便通過將這些對象與Lock對象組合使用,為每個對象提供多個等待集(wait-set)。在這種情況下,Lock 替代了同步方法或同步代碼塊,Condition替代了同步監(jiān)視鎖的功能。
Condition實(shí)例實(shí)質(zhì)上被綁定在一個Lock對象上。要獲得特定Lock實(shí)例的Condition實(shí)例,調(diào)用Lock對象newCondition()方法即可。Condtion類提供了如下三個方法:
await():類似于隱式同步監(jiān)視器上的wait()方法,導(dǎo)致當(dāng)前線程等待,直到其他線程調(diào)用該Condtion的signal ()方法或signalAll ()方法來喚醒該線程。該await方法有更多變體:long awaitNanos(long nanosTimeout)、void awaitUninterruptibly()、awaitUntil(Date deadline)等,可以完成更豐富的等待操作。
signal ():喚醒在此Lock對象上等待的單個線程。如果所有線程都在該Lock對象上等待,則會選擇喚醒其中一個線程。選擇是任意性的。只有當(dāng)前線程放棄對該Lock對象的鎖定后(使用await()方法),才可以執(zhí)行被喚醒的線程。
signalAll():喚醒在此Lock對象上等待的所有線程。只有當(dāng)前線程放棄對該該Lock對象的鎖定后,才可以執(zhí)行被喚醒的線程。
二 代碼
1 Account類
public class Account
{
// 顯式定義Lock對象
private final Lock lock = new ReentrantLock();
// 獲得指定Lock對象對應(yīng)的Condition
private final Condition cond = lock.newCondition();
// 封裝賬戶編號、賬戶余額的兩個成員變量
private String accountNo;
private double balance;
// 標(biāo)識賬戶中是否已有存款的旗標(biāo)
private boolean flag = false;
public Account(){}
// 構(gòu)造器
public Account(String accountNo , double balance)
{
this.accountNo = accountNo;
this.balance = balance;
}
// accountNo的setter和getter方法
public void setAccountNo(String accountNo)
{
this.accountNo = accountNo;
}
public String getAccountNo()
{
return this.accountNo;
}
// 因此賬戶余額不允許隨便修改,所以只為balance提供getter方法,
public double getBalance()
{
return this.balance;
}
public void draw(double drawAmount)
{
// 加鎖
lock.lock();
try
{
// 如果flag為假,表明賬戶中還沒有人存錢進(jìn)去,取錢方法阻塞
if (!flag)
{
cond.await();
}
else
{
// 執(zhí)行取錢
System.out.println(Thread.currentThread().getName()
+ " 取錢:" + drawAmount);
balance -= drawAmount;
System.out.println("賬戶余額為:" + balance);
// 將標(biāo)識賬戶是否已有存款的旗標(biāo)設(shè)為false。
flag = false;
// 喚醒其他線程
cond.signalAll();
}
}
catch (InterruptedException ex)
{
ex.printStackTrace();
}
// 使用finally塊來釋放鎖
finally
{
lock.unlock();
}
}
public void deposit(double depositAmount)
{
lock.lock();
try
{
// 如果flag為真,表明賬戶中已有人存錢進(jìn)去,則存錢方法阻塞
if (flag) // ①
{
cond.await();
}
else
{
// 執(zhí)行存款
System.out.println(Thread.currentThread().getName()
+ " 存款:" + depositAmount);
balance += depositAmount;
System.out.println("賬戶余額為:" + balance);
// 將表示賬戶是否已有存款的旗標(biāo)設(shè)為true
flag = true;
// 喚醒其他線程
cond.signalAll();
}
}
catch (InterruptedException ex)
{
ex.printStackTrace();
}
// 使用finally塊來釋放鎖
finally
{
lock.unlock();
}
}
// 下面兩個方法根據(jù)accountNo來重寫hashCode()和equals()方法
public int hashCode()
{
return accountNo.hashCode();
}
public boolean equals(Object obj)
{
if(this == obj)
return true;
if (obj !=null
&& obj.getClass() == Account.class)
{
Account target = (Account)obj;
return target.getAccountNo().equals(accountNo);
}
return false;
}
}2 DrawThread線程類
public class DrawThread extends Thread
{
// 模擬用戶賬戶
private Account account;
// 當(dāng)前取錢線程所希望取的錢數(shù)
private double drawAmount;
public DrawThread(String name , Account account
, double drawAmount)
{
super(name);
this.account = account;
this.drawAmount = drawAmount;
}
// 重復(fù)100次執(zhí)行取錢操作
public void run()
{
for (int i = 0 ; i < 100 ; i++ )
{
account.draw(drawAmount);
}
}
}3 DepositThread線程類
public class DepositThread extends Thread
{
// 模擬用戶賬戶
private Account account;
// 當(dāng)前取錢線程所希望存款的錢數(shù)
private double depositAmount;
public DepositThread(String name , Account account
, double depositAmount)
{
super(name);
this.account = account;
this.depositAmount = depositAmount;
}
// 重復(fù)100次執(zhí)行存款操作
public void run()
{
for (int i = 0 ; i < 100 ; i++ )
{
account.deposit(depositAmount);
}
}
}4 測試類
public class DrawTest
{
public static void main(String[] args)
{
// 創(chuàng)建一個賬戶
Account acct = new Account("1234567" , 0);
new DrawThread("取錢者" , acct , 800).start();
new DepositThread("存款者甲" , acct , 800).start();
new DepositThread("存款者乙" , acct , 800).start();
new DepositThread("存款者丙" , acct , 800).start();
}
}三 運(yùn)行結(jié)果
......
存款者丙 存款:800.0
賬戶余額為:800.0
取錢者 取錢:800.0
賬戶余額為:0.0
存款者甲 存款:800.0
賬戶余額為:800.0
取錢者 取錢:800.0
賬戶余額為:0.0
存款者丙 存款:800.0
賬戶余額為:800.0
取錢者 取錢:800.0
賬戶余額為:0.0
存款者甲 存款:800.0
賬戶余額為:800.0
取錢者 取錢:800.0
賬戶余額為:0.0
存款者丙 存款:800.0
賬戶余額為:800.0
取錢者 取錢:800.0
賬戶余額為:0.0
存款者甲 存款:800.0
賬戶余額為:800.0
Java的特點(diǎn)有哪些 1.Java語言作為靜態(tài)面向?qū)ο缶幊陶Z言的代表,實(shí)現(xiàn)了面向?qū)ο罄碚?,允許程序員以優(yōu)雅的思維方式進(jìn)行復(fù)雜的編程。 2.Java具有簡單性、面向?qū)ο蟆⒎植际?、安全性、平臺獨(dú)立與可移植性、動態(tài)性等特點(diǎn)。 3.使用Java可以編寫桌面應(yīng)用程序、Web應(yīng)用程序、分布式系統(tǒng)和嵌入式系統(tǒng)應(yīng)用程序等。
以上就是如何在Java中使用Condition控制線程通信,小編相信有部分知識點(diǎn)可能是我們?nèi)粘9ぷ鲿姷交蛴玫降?。希望你能通過這篇文章學(xué)到更多知識。更多詳情敬請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。