PTA:jmu-Java-07多线程-同步访问

发布时间:2023年12月18日

已有现已有Account类,拥有
属性:
private int balance
方法:
相应的getter方法。

要求为该类编写:

void deposit(int money)?//存钱,在余额的基础上加上money
void withdraw(int money)?//取钱,在余额的基础上减去money

注意:

  1. 取钱时如果balance<0的时候,会抛出异常。在多线程情况下,如只有一个存钱的线程,但是有多个取钱的线程,很可能会抛出异常。
  2. 需要编写完整的deposit方法与withdraw的前半部分代码解决该问题。

裁判测试程序:?

import java.util.Scanner;

//这里是已有的Account类前半部分的代码
/*这里是deposit代码*/
/*这里是withdraw代码的前半部分*/
? ? if(balance<0) //这里是withdraw代码的后半部分。
? ? ? ? throw new IllegalStateException(balance+""); ? ?
? ? }

/*系统已有代码,无需关注*/

?输入样例:

分别为初始余额、存钱次数、存钱金额
取钱次数、取钱金额。有3个线程。

0 100000 12
100000 4
?

输出样例:

余额:使用线程跑出的结果。
余额:存钱次数*存钱金额 - 取钱次数*取钱金额*3

0
0

代码长度限制

16 KB

时间限制

800 ms

内存限制

64 MB

本题注意点:?

1.本题已经编写好Account类,不需要再写属性和方法。

2.这题是多线程问题,不允许多线程执行取钱和存钱行为,所以要使用synchronized来锁住,只允许其中一个线程访问。

3.withdraw代码只要求编写前半部分,而且if(balance<0)语句是有一个右大括号,所以编写withdraw前半部分代码记得去掉一个右大括号。

知识点:

? wait()方法:使用wait()方法时,通常需要将其放在while循环内,等待结束后重新检查条件是否满足,以防止虚假唤醒或其他条件变化导致程序出错。

? notifyAll()方法:如图所示,唤醒所有线程,一般不用notify(),其随机性太强。

思路:

本题涉及生产者和消费者(等待唤醒机制),是消费者(取钱)等待的类型。如果余额充足,才会进行取钱,不然就会进行等待,不会再次进行取钱行为,除非被唤醒才会再次执行。如果进行存钱操作,就会唤醒所有线程。如此反复即可。

代码:

public synchronized void deposit(int money){
    balance+=money;
    notifyAll();
}
public synchronized void withdraw(int money){
    while(balance<money){
        try{
            wait();
        }catch(InterruptedException e){
            e.printStackTrace();
        }
    }
    balance-=money;
    

文章来源:https://blog.csdn.net/m0_73680520/article/details/135069989
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。