java 线程同步condtion_Java:多线程,使用同步锁(Lock)时利用Condition类实现线程间通信...
[我們不僅可以使用synchronized來實(shí)現(xiàn)多線程同步,還可以通過創(chuàng)建鎖對(duì)象來實(shí)現(xiàn)多線程的同步,還是上次模擬取現(xiàn)的操作,這次利用lock對(duì)象實(shí)現(xiàn)同步,下面是代碼:? ??import
如果程序不使用synchronized關(guān)鍵字來保證同步,而是直接使用Lock對(duì)象來保證同步,則系統(tǒng)中不存在隱式的同步監(jiān)視器,也就不能用wait()、notify()、notifyAll()方法進(jìn)行線程通信了。當(dāng)使用Lock對(duì)象來保證同步時(shí),Java提供了Condition類來協(xié)調(diào)線程間的通信。
本示范簡(jiǎn)單模擬銀行帳戶的存取款活動(dòng),帳戶余額大于等于取款金額時(shí)允許取款;帳戶余額小于1000時(shí)允許存款(這與真實(shí)業(yè)務(wù)邏輯不符合,只是技術(shù)上需要才如此做的,否則存款一下子全存完就不好玩了)。[1>Lock:????????Lock比傳統(tǒng)線程模型中的Synchronied方式更加面向?qū)ο?與生活中的鎖類似,鎖本身也應(yīng)該是一個(gè)對(duì)象.兩個(gè)線程執(zhí)行的代碼段要實(shí)現(xiàn)同步互斥的效果,它們必須用同
1. 實(shí)體Account類
package com.clzhang.sample.thread;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class Account {
// 鎖對(duì)象
private final Lock lock = new ReentrantLock();
// Condition對(duì)象
private final Condition condDeposit = lock.newCondition();
private final Condition condWithdraw = lock.newCondition();
// 為避免double類型計(jì)算的誤差,balance類型設(shè)計(jì)為int的
private int balance;
public Account(int balance) {
this.balance = balance;
}
public void withdraw(int drawAmount) {
// 加鎖
lock.lock();
try {
// 如果帳戶余額不足,則取錢方法阻塞
while (balance < drawAmount)
condWithdraw.await();
// 執(zhí)行取錢
balance -= drawAmount;
System.out.println(Thread.currentThread().getName() + " 取錢:" + drawAmount + "賬戶余額為:"
+ balance);
// 喚醒存款線程
condDeposit.signal();
} catch (InterruptedException ex) {
ex.printStackTrace();
} finally {
lock.unlock();
}
}
// 按照目前設(shè)計(jì),帳戶余額大于1000后不讓存款,必須先取款后才能再存。
// 這與真實(shí)業(yè)務(wù)邏輯不符合,只是技術(shù)上需要才如此做的,否則存款一下子全存完就不好玩了。
public void deposit(int depositAmount) {
lock.lock();
try {
// 如果帳戶余額大于1000,存錢方法阻塞
while (balance > 1000)
condDeposit.await();
// 執(zhí)行存款
balance += depositAmount;
System.out.println(Thread.currentThread().getName() + " 存款:" + depositAmount + "賬戶余額為:"
+ balance);
// 喚醒取款線程
condWithdraw.signal();
} catch (InterruptedException ex) {
ex.printStackTrace();
} finally {
lock.unlock();
}
}
}
2. 調(diào)用類(DepositDrawTest類)
package com.clzhang.sample.thread;
class DrawThread extends Thread {
// 模擬用戶賬戶
private Account account;
// 每次取錢數(shù)
private int drawAmount;
public DrawThread(String name, Account account, int drawAmount) {
super(name);
this.account = account;
this.drawAmount = drawAmount;
}
@Override
public void run() {
for (int i = 0; i < 3; i++) {
account.withdraw(drawAmount);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
}
}
class DepositThread extends Thread {
// 模擬用戶賬戶
private Account account;
// 每次存錢數(shù)
private int depositAmount;
public DepositThread(String name, Account account, int depositAmount) {
super(name);
this.account = account;
this.depositAmount = depositAmount;
}
@Override
public void run() {
for (int i = 0; i < 3; i++) {
account.deposit(depositAmount);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
}
}
public class DepositDrawTest {
public static void main(String[] args) {
// 創(chuàng)建一個(gè)賬戶,初始帳戶余額為0
Account acct = new Account(0);
// 注意下面的取款與存款的balance參數(shù)值需要匹配,
// 否則可能造成存款過多而不讓存,然后又沒有人取款導(dǎo)致程序無法正常終止的問題。
new DrawThread("取錢者1", acct, 400).start();
new DrawThread("取錢者2", acct, 600).start();
new DepositThread("存款者甲", acct, 600).start();
new DepositThread("存款者乙", acct, 200).start();
new DepositThread("存款者丙", acct, 400).start();
}
}
輸出:
存款者甲 存款:600賬戶余額為:600
存款者乙 存款:200賬戶余額為:800
存款者丙 存款:400賬戶余額為:1200
取錢者1 取錢:400賬戶余額為:800
取錢者2 取錢:600賬戶余額為:200
存款者乙 存款:200賬戶余額為:400
存款者甲 存款:600賬戶余額為:1000
取錢者2 取錢:600賬戶余額為:400
存款者丙 存款:400賬戶余額為:800
取錢者1 取錢:400賬戶余額為:400
存款者甲 存款:600賬戶余額為:1000
存款者丙 存款:400賬戶余額為:1400
取錢者1 取錢:400賬戶余額為:1000
存款者乙 存款:200賬戶余額為:1200
取錢者2 取錢:600賬戶余額為:600
3. 總結(jié)
如果取款金額大于余額則不讓取款,等存款隊(duì)列繼續(xù)存錢,余額足夠支付時(shí)再讓取款。
如果存款過多(大于1000),則存款不讓存了,等取款隊(duì)列把錢取走,余額降低到1000以下時(shí),可以繼續(xù)存款。
這樣就允許多次連續(xù)取款(只要帳戶有錢),多次連續(xù)存款(余額不能大于1000),而不是存款、取款依次調(diào)用。[ 線程之間除了同步互斥,還要考慮通信。在Java5之前我們的通信方式為:wait 和 notify。那么Condition的優(yōu)勢(shì)是支持多路等待,就是我可以定義多個(gè)Condition,每個(gè)condition
總結(jié)
以上是生活随笔為你收集整理的java 线程同步condtion_Java:多线程,使用同步锁(Lock)时利用Condition类实现线程间通信...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 湖北高校发明考试防作弊专利:通过头部姿态
- 下一篇: java中bubblesort是什么意思