當(dāng)前位置:首頁 > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > Java中線程的同步(三)
Java中線程的同步(三)
時(shí)間:2018-09-25 來源:未知
java允許多線程并發(fā)控制,當(dāng)多個(gè)線程同時(shí)操作一個(gè)可共享的資源變量時(shí)(如數(shù)據(jù)的增刪改查), 將會(huì)導(dǎo)致數(shù)據(jù)不準(zhǔn)確,相互之間產(chǎn)生沖突,因此加入同步鎖以避免在該線程沒有完成操作之前,被其他線程的調(diào)用,從而保證了該變量的唯一性和準(zhǔn)確性。
我們來看java中第三種同步的方式,使用可重入的鎖。
package com.farsight.thread3;
import java.util.concurrent.locks.ReentrantLock;
/**
* 封裝賬戶編號(hào),賬戶余額
* @author xj
*
*/
class Account{
// 定義一個(gè)可重入的鎖對(duì)象
public final ReentrantLock lock = new ReentrantLock();
private String accountNo;
private double balance;
public Account(){
}
public Account(String accountNo, double balance){
this.accountNo = accountNo;
this.balance = balance;
}
public String getAccountNo() {
return accountNo;
}
public void setAccountNo(String accountNo) {
this.accountNo = accountNo;
}
public double getBalance() {
return balance;
}
public void draw(double drawAmount){
// 加鎖
lock.lock();
try{
// 賬戶余額大于取錢的數(shù)目
if(balance >= drawAmount){
System.out.println(Thread.currentThread().getName() + "取錢成功! 吐出鈔票: " + drawAmount);
//人為制造cpu調(diào)度,使并發(fā)產(chǎn)生
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 修改余額
balance -= drawAmount;
}
else{
System.out.println(Thread.currentThread().getName() + "取錢失敗!余額不足!");
}
}
finally {
// 釋放鎖
lock.unlock();
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((accountNo == null) ? 0 : accountNo.hashCode());
long temp;
temp = Double.doubleToLongBits(balance);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Account other = (Account) obj;
if (accountNo == null) {
if (other.accountNo != null)
return false;
}
else if (!accountNo.equals(other.accountNo))
return false;
if (Double.doubleToLongBits(balance) != Double
.doubleToLongBits(other.balance))
return false;
return true;
}
}
/**
* 定義一個(gè)取錢的線程類,該線程類根據(jù)執(zhí)行賬戶、取錢
* 數(shù)量進(jìn)行取錢操作,余額不足時(shí)無法提取現(xiàn)金。
* @author xj
*
*/
class DrawThread extends Thread{
// 定義一個(gè)用戶類,取錢數(shù)量
private Account account;
private double drawAmount;
public DrawThread(String name, Account account, double drawAmount){
super(name);
this.account = account;
this.drawAmount = drawAmount;
}
public void run(){
account.draw(drawAmount);
}
}
public class ThreadDemon3 {
public static void main(String[] args) {
// 創(chuàng)建一個(gè)模擬戶
Account acct = new Account("1234567", 10000);
//模擬兩個(gè)線程對(duì)同一個(gè)賬戶取錢
new DrawThread("甲", acct, 6000).start();
new DrawThread("乙", acct, 5000).start();
}
}

