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

歡迎訪問 生活随笔!

生活随笔

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

java

java 线程同步condtion_Java:多线程,使用同步锁(Lock)时利用Condition类实现线程间通信...

發(fā)布時(shí)間:2023/12/19 java 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 线程同步condtion_Java:多线程,使用同步锁(Lock)时利用Condition类实现线程间通信... 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

[我們不僅可以使用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)容,希望文章能夠幫你解決所遇到的問題。

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