/**
*
*/
package thread;/**
* @description 线程同步
*
*/
public class SynchronizedTest {
public static void main(String[] args) {
Account account = new Account("10011",0);
new DepositThread2("存钱线程",account,300).start();
new DrawThread2("取钱线程",account,300).start();
}
}
/**
* @description 账户-存/取
*
*/
class Account2{
private String accountNo;
private double balance;//余额
private boolean flag = false;//true代表可取 ,false代表可存
public Account2(String accountNo,double balance) {
this.accountNo = accountNo;
this.balance = balance;
}
/**
* @return the accountNo
*/
public String getAccountNo() {
return accountNo;
}
/**
* @param accountNo the accountNo to set
*/
public void setAccountNo(String accountNo) {
this.accountNo = accountNo;
}
/**
* @return the balance
*/
public double getBalance() {
return balance;
}
/**
* @description 取钱
* @param drawAmount
*/
public synchronized void draw(double drawAmount){
try{
if(flag){//flag=true , 表示账户还有钱,等待将钱取走
System.out.println(Thread.currentThread().getName()+" 取钱:"+drawAmount);
balance -= drawAmount;
System.out.println("账户余额:"+balance);
flag = false;//可以存钱
notifyAll();
}else{
wait();
}
}catch(Exception e){
}
}
/**
* @description 存钱
* @param drawAmount
*/
public synchronized void deposit(double depositAmount){
try{
if(flag){//flag=true , 表示账户还有钱,等待将钱取走
wait();
}else{
System.out.println(Thread.currentThread().getName()+" 存钱:"+depositAmount);
balance += depositAmount;
System.out.println("账户余额:"+balance);
flag = true;//可以取钱
notifyAll();
}
} catch (InterruptedException e) {
}
}
}
/**
* @decription 存钱线程
*
*/
class DepositThread2 extends Thread{
private Account account;
private double drawAmount=300;
public DepositThread2(String name,Account account,double drawAmount) {
super(name);
this.account = account;
this.drawAmount = drawAmount;
}
/* (non-Javadoc)
* @see java.lang.Thread#run()
*/
@Override
public void run() {
for(int i=0;i<5;i++){
account.deposit(drawAmount);
}
}
}
/**
* @decription 取钱线程
*
*/
class DrawThread2 extends Thread{
private Account account;
private double drawAmount = 300;
public DrawThread2(String name,Account account,double drawAmount) {
super(name);
this.account = account;
this.drawAmount = drawAmount;
}
/* (non-Javadoc)
* @see java.lang.Thread#run()
*/
@Override
public void run() {
for(int i=0;i<5;i++){
account.draw(drawAmount);
}
}
}
在存钱线程里使用循环存了5次钱,每次存后再等待取钱线程取钱. 从控制台的输出:只存了3次或4次, 并且程序偶尔不能结束.
请问是不是死锁了, 要如何解决?
解决方案 »
- 谁有java udp 广播的代码哦
- 有没有动态生成方法的...办法
- 桌面应用,选swing还是swt/jface?
- GridBagLayout的实例
- 接口可以继承接口吗
- mysql中,如何取交集??
- 大家帮帮忙,教我解决一下一个java问题
- 数据库和JComboBox的结合应用
- 在j2se1.4下运行assert (2+2)==5;出现warning: as of release 1.4, assert is a keyword, and may not be used as an identifier
- 怎么样用map组装出来这个json
- 通常这种问题,非牛人解答不可!
- [诡异问题]vista下dom4j读取文件抛Connection timed out异常
将存钱和取钱的if(flag)改为while(flag)逻辑请自己研究下。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;/**
* @description 线程同步
*/
public class LockTest {
public static void main(String[] args) {
Account account = new Account("10011",0);
new DepositThread("存钱线程",account,300).start();
new DrawThread("取钱线程",account,300).start();
}
}
/**
* @description 账户-存/取
*/
class Account{
private final Lock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
private String accountNo;
private double balance;//余额
private boolean flag = false;//true代表可取 ,false代表可存
public Account(String accountNo,double balance) {
this.accountNo = accountNo;
this.balance = balance;
}
/**
* @return the accountNo
*/
public String getAccountNo() {
return accountNo;
}
/**
* @param accountNo the accountNo to set
*/
public void setAccountNo(String accountNo) {
this.accountNo = accountNo;
}
/**
* @return the balance
*/
public double getBalance() {
return balance;
}
/**
* @description 取钱
* @param drawAmount
*/
public void draw(double drawAmount){
lock.lock();//加锁
try{
if(flag){//flag=true , 表示账户还有钱,等待将钱取走
System.out.println(Thread.currentThread().getName()+" 取钱:"+drawAmount);
balance -= drawAmount;
System.out.println("账户余额:"+balance);
flag = false;//可以存钱
condition.signal();
}else{
condition.await();
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
lock.unlock();//解锁
}
}
/**
* @description 存钱
* @param drawAmount
*/
public void deposit(double depositAmount){
lock.lock();//加锁
try{
if(flag){//flag=true , 表示账户还有钱,等待将钱取走
condition.await();
}else{
System.out.println(Thread.currentThread().getName()+" 存钱:"+depositAmount);
balance += depositAmount;
System.out.println("账户余额:"+balance);
flag = true;//可以取钱
condition.signal();
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
lock.unlock();//解锁
}
}
}
/**
* @decription 存钱线程
*/
class DepositThread extends Thread{ private Account account;
private double drawAmount=300;
public DepositThread(String name,Account account,double drawAmount) {
super(name);
this.account = account;
this.drawAmount = drawAmount;
} /* (non-Javadoc)
* @see java.lang.Thread#run()
*/
@Override
public void run() {
for(int i=0;i<5;i++){
account.deposit(drawAmount);
}
}
}
/**
* @decription 取钱线程
* @author wang_kang
*
*/
class DrawThread extends Thread{
private Account account;
private double drawAmount = 300;
public DrawThread(String name,Account account,double drawAmount) {
super(name);
this.account = account;
this.drawAmount = drawAmount;
}
/* (non-Javadoc)
* @see java.lang.Thread#run()
*/
@Override
public void run() {
for(int i=0;i<5;i++){
account.draw(drawAmount);
}
}
}用lock也是一样呢
/**
* @description 线程同步
*
*/
public class SynchronizedTest {
public static void main(String[] args) {
Account2 account = new Account2("10011",0);
new DepositThread2("存钱线程",account,300).start();
new DrawThread2("取钱线程",account,300).start();
}
}
/**
* @description 账户-存/取
*
*/
class Account2{
private String accountNo;
private double balance;//余额
private boolean flag = false;//true代表可取 ,false代表可存
public Account2(String accountNo,double balance) {
this.accountNo = accountNo;
this.balance = balance;
}
/**
* @return the accountNo
*/
public String getAccountNo() {
return accountNo;
}
/**
* @param accountNo the accountNo to set
*/
public void setAccountNo(String accountNo) {
this.accountNo = accountNo;
}
/**
* @return the balance
*/
public double getBalance() {
return balance;
}
/**
* @description 取钱
* @param drawAmount
*/
public synchronized void draw(double drawAmount){
try{
while(!flag){
wait();
}
if(flag){//flag=true , 表示账户还有钱,等待将钱取走
System.out.println(Thread.currentThread().getName()+" 取钱:"+drawAmount);
balance -= drawAmount;
System.out.println("账户余额:"+balance);
flag = false;//可以存钱
notifyAll();
}
}catch(Exception e){
}
}
/**
* @description 存钱
* @param drawAmount
*/
public synchronized void deposit(double depositAmount){
try{
while(flag){
wait();
}
if(!flag){//flag=true , 表示账户还有钱,等待将钱取走
System.out.println(Thread.currentThread().getName()+" 存钱:"+depositAmount);
balance += depositAmount;
System.out.println("账户余额:"+balance);
flag = true;//可以取钱
notifyAll();
}
} catch (InterruptedException e) {
}
}
}
/**
* @decription 存钱线程
*
*/
class DepositThread2 extends Thread{
private Account2 account;
private double drawAmount=300;
public DepositThread2(String name,Account2 account,double drawAmount) {
super(name);
this.account = account;
this.drawAmount = drawAmount;
}
/* (non-Javadoc)
* @see java.lang.Thread#run()
*/
@Override
public void run() {
for(int i=0;i<5;i++){
account.deposit(drawAmount);
}
}
}
/**
* @decription 取钱线程
*
*/
class DrawThread2 extends Thread{
private Account2 account;
private double drawAmount = 300;
public DrawThread2(String name,Account2 account,double drawAmount) {
super(name);
this.account = account;
this.drawAmount = drawAmount;
}
/* (non-Javadoc)
* @see java.lang.Thread#run()
*/
@Override
public void run() {
for(int i=0;i<5;i++){
account.draw(drawAmount);
}
}
}