I am learning Java multithreading. This is the the code I write.
package com.company;
public class Account {
private double balance = 100;
public synchronized double getBalance() {
synchronized (this){
return balance;
}
}
public void setBalance(double balance) {
this.balance = balance;
}
public boolean withdraw(double amount,String name){
if(this.getBalance()>amount){
if(Thread.currentThread().getName().equals("customer0")){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.setBalance(this.getBalance() - amount);
System.out.println(Thread.currentThread().getName() + " withdraw " + amount);
System.out.println("Hello, " + Thread.currentThread().getName() + " You current balance is " + this.getBalance());
return true;
}
else{
System.out.println("Sorry, " + Thread.currentThread().getName() + ". Your current balance is " + this.getBalance() + " and you cannot withdraw " + amount);
//System.out.println("Welcome, " + Thread.currentThread().getName() + " Your current balance is " + this.getBalance());
return false;
}
}
}
and the main class
package com.company;
import org.omg.PortableServer.THREAD_POLICY_ID;
public class Main implements Runnable {
Account account = new Account();
public static void main(String[] args){
Main main = new Main();
for(int i= 0; i< 2; i++) {
Thread c1 = new Thread(main, "customer" + i);
c1.start();
}
}
#Override
public void run() {
System.out.println(Thread.currentThread().getName() + "'s balance is " + account.getBalance());
account.withdraw(60, Thread.currentThread().getName());
//
}
}
I put synchronized keyword at getBalance() to make sure it can be accessible only by one thread a time. But still I get the negative balance.
customer0's balance is 100.0
customer1's balance is 100.0
customer1 withdraw 60.0
Hello, customer1 You current balance is 40.0
customer0 withdraw 60.0
Hello, customer0 You current balance is -20.0
What did I do wrong?
I think you should be synchronizing withdraw and balance.
Your code just now could let two threads withdraw at the same time but not let them check the balance at the same time.
You only want one thread withdrawing & one thread checking the balance at one time.
(Thanks for the edit suggestions)
Related
I have
System.out.printf("$%.2f\t $%.2f\n ",c.getDifference(),c.getAccValue());
but c.getAccValue() always gives me the wrong output and I have no idea why. The formula for getDifference() is getAccValue() - principal, and that output is correct.
I used input 5000 8.25 5 quarterly
CD class:
package cd;
public class CD {
private int time; //in years, t
private double interest; //interest rate, r
private int principal; //principal, p
private String number;//number of times compounded, n
public CD(int time, double interest, int principal, String number){
this.time = time;
this.interest = interest;
this.principal = principal;
this.number = number;
}
public int getTime(){
return time;
}
public double getInterest(){
return interest;
}
public int getPrincipal(){
return principal;
}
public String getNumber(){
return number;
}
public double getAccValue(){
double A = 0;
interest = interest/100;
if( "daily".equals(number)) {
A = Math.pow(1 + interest/365, 365*time) * principal;
}
else if ("weekly".equals(number)){
A = Math.pow(1 + interest/52, 52*time) * principal;
}
else if ("monthly".equals(number)){
A = Math.pow(1 + interest/12, 12*time) * principal;
}
else if ("quarterly".equals(number)){
A = Math.pow(1 + interest/3, 3*time) * principal;
}
else if ("semiannually".equals(number)){
A = Math.pow(1 + interest/2, 2*time) * principal;
}
else if ("annually".equals(number)){
A = Math.pow(1 + interest/1, 1*time) * principal;
}
return A;
}
public double getDifference(){
return getAccValue() - principal;
}
}
CDTest class:
package cd;
import java.util.Scanner;
import javax.swing.JOptionPane;
public class CDTest {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
String input = JOptionPane.showInputDialog("Enter Principal value, "
+ "Interest rate, time (in years), " + " and number of months"
+ " compunded" + "\n(Separated by spaces)");
Scanner in = new Scanner(input);
int principal = in.nextInt();
double interest = in.nextDouble();
int time = in.nextInt();
String number = in.next();
CD c = new CD(time, interest, principal, number);
System.out.println("Principal " + "Interest " + "Maturity " +
"Number Compounded " + "Amount Gained " +
"Accumulated Value " + "");
System.out.println("========= " + "======== " + "======== "
+ "================= " + "============= " +
"================= ");
System.out.printf(" $" + c.getPrincipal() + "\t ");
System.out.print(c.getInterest() + "%" + "\t ");
System.out.print(c.getTime() + "\t ");
System.out.print(c.getNumber() +" \t");
System.out.printf("$%.2f\t $%.2f\n ",c.getDifference(),c.getAccValue());
}
}
Thanks for the help in advance
Edit:
Current output is:
Principal Interest Maturity Number Compounded Amount Gained
========= ======== ======== ================= =============
$5000 8.25% 5 quarterly $2510.99
Accumulated Value
=================
$5020.66
Expected output is:
Principal Interest Maturity Number Compounded Amount Gained
========= ======== ======== ================= =============
$5000 8.25% 5 quarterly $2510.99
Accumulated Value
=================
$7510.99
else if ("quarterly".equals(number)){
A = Math.pow(1 + interest/3, 3*time) * principal;
You're multiplying by 3. But there are 4 quarters in a year. So, I would double check this formula.
Also, you have this line:
interest = interest/100;
in getAccValue. This permanently changes the interest rate. But, getAccValue is called by getDifference. So when the difference is calculated, it divides the interest rate by 100 - and then when getAccValue is called by itself, it divides the interest rate by 100 again. So now your interest rate is tiny and it's showing hardly any money made at all.
this is my first question here, so here it goes, I have tried this for ages with no luck, I am new to Java (studying it) and I have an assignment and I cant get this to work (only the first part works)...thanks in advanced for any help you can give me! :)
**Write a program to read in a non-specified number of Employee Salaries from the user. After each Employee Salary is entered the program should then calculate the Bonus for each employee. The bonus is to be calculated as a percentage of the Salary, according to the table shown below:
Salary Bonus Rate
Less than €10,000 5%
Between €10,000 and less than €20,000 10%
Between €20,000 and less than €30,000 15%
€30,000 or more 20%
The Program should output the Bonus Rate, Bonus Amount, and Total Salary for each Employee after the salary is entered.
When the user has entered the details for all employees, the program should then output the following:
Overall Total Bonuses paid
Overall Total Salaries paid (including bonuses)
Average Bonus
Your program should let the user indicate that they have finished entering results.
Add extra checks to your program so that negative figures are rejected by the program along with a suitable error message.
Test your program thoroughly, so that it works under all possible conditions.
Input/Output from the program should be attractively displayed on the screen.
import java.util.Scanner;
class Salary
{
public static void main (String args [])
{
Scanner myInput = new Scanner (System.in);
double salary =0, bonusRate =0, bonusAmount=0, salaryTotal=0, totalBonus=0, averageBonus=0, totalSalaries=0;
int salaryCounter=0;
char response;
do
{
System.out.println("Press a to enter a salary or press 'q' to quit");
response=myInput.next().charAt(0);
switch(response)
{
case 'a':
do
{
System.out.println("Enter employee salary or press q to quit");
salary = myInput.nextDouble();
if (salary <=0)
{
System.out.println("Invalid entry please enter Salary again ");
}
else if (salary >0 && salary <=10000)
{
System.out.println("*************************************************************");
System.out.println("The bonus rate is 5%");
bonusRate = salary * .05;
System.out.println("The bonus is " + bonusRate);
salaryTotal= salary + bonusRate;
System.out.println("The Total salary " + salaryTotal);
salaryCounter=salaryCounter+1;
System.out.println("*************************************************************");
}
else if (salary >10000 && salary <=20000)
{
System.out.println("*************************************************************");
System.out.println("The bonus rate is 10%");
bonusRate = salary * .10;
System.out.println("The bonus is " + bonusRate);
salaryTotal= salary + bonusRate;
System.out.println("The Total salary " + salaryTotal);
salaryCounter=salaryCounter+1;
System.out.println("*************************************************************");
}
else if (salary >20000 && salary <=30000)
{
System.out.println("*************************************************************");
System.out.println("The bonus rate is 15%");
bonusRate = salary * .15;
System.out.println("The bonus is " + bonusRate);
salaryTotal= salary + bonusRate;
System.out.println("The Total salary " + salaryTotal);
salaryCounter=salaryCounter+1;
System.out.println("*************************************************************");
}
else if (salary >30000)
{
System.out.println("*************************************************************");
System.out.println("The bonus rate is 20%");
bonusRate = salary * .20;
System.out.println("The bonus is " + bonusRate);
salaryTotal= salary + bonusRate;
System.out.println("The Total salary " + salaryTotal);
salaryCounter=salaryCounter+1;
System.out.println("*************************************************************");
}
//else
//{ //do i need to get rid of this?
// System.out.println("");
//}
}while(salary <=0);{
break;
}case 'q':
salaryCounter = salaryCounter+1;
bonusAmount= salary*bonusRate;
salaryTotal=salary+bonusAmount;
totalBonus=totalBonus+bonusAmount;
totalSalaries=totalSalaries+salaryTotal;
averageBonus=totalBonus*salaryCounter;
System.out.printf("The Total Salaries paid including Bonus is %.2f " , totalSalaries);
System.out.println("Euro");
System.out.printf("The Total of Bonuses paid is %.2f ", totalBonus);
System.out.println("Euro");
System.out.printf("The Total of Average Bonuses paid is %.2f ", averageBonus);
System.out.println("Euro");
break;
}//end do
//end switch
}while (response != 'q');{
//do while loop to repeat until 'q' is entered.
} //end do while loop
}//end main
}//end class
You can create two different files for your requirements: one pojo class containing the attributes of the employee and second main app where the user interacts with the program.
Salary.java
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
public class Salary {
private static int count = 0;
private int empId;
private double salary;
private int bonusRate;
private double bonusAmount;
private double totalSalary;
//Getters and Setters
public int getEmpId() {
return empId;
}
public double getTotalSalary() {
return totalSalary;
}
public void setTotalSalary(double totalSalary) {
this.totalSalary = totalSalary;
}
public void setEmpId(int empId) {
this.empId = empId;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public int getBonusRate() {
return bonusRate;
}
public void setBonusRate(int bonusRate) {
this.bonusRate = bonusRate;
}
public double getBonusAmount() {
return bonusAmount;
}
public void setBonusAmount(double bonusAmount) {
this.bonusAmount = bonusAmount;
}
//Constructors
public Salary(int empId, double salary, int bonusRate, double bonusAmount,
double totalSalary) {
super();
this.empId = empId;
this.salary = salary;
this.bonusRate = bonusRate;
this.bonusAmount = bonusAmount;
this.totalSalary = totalSalary;
}
public Salary() {
super();
count = count + 1;
this.empId = count;
}
//toString
#Override
public String toString() {
return "Salary [empId=" + empId + ", salary=" + salary + ", bonusRate="
+ bonusRate + ", bonusAmount=" + bonusAmount + ", totalSalary="
+ totalSalary + "]";
}
//calculation function
public void calculateBonus(){
double bonus;
if(this.getSalary()<10000){
this.setBonusRate(5);
bonus = this.getSalary() + 0.05*(this.getSalary());
}else if(this.getSalary()<20000){
this.setBonusRate(10);
bonus = this.getSalary() + 0.10*(this.getSalary());
}else if(this.getSalary()<30000){
this.setBonusRate(15);
bonus = this.getSalary() + 0.15*(this.getSalary());
}else{
this.setBonusRate(20);
bonus = this.getSalary() + 0.20*(this.getSalary());
}
this.setBonusAmount(bonus);
this.setTotalSalary(this.getSalary() + bonus);
}
}
MainApp.java
import java.util.ArrayList;
import java.util.Scanner;
public class MainApp {
public static void main(String[] args) {
ArrayList<Salary> salaries = new ArrayList<Salary>();
Scanner sc = new Scanner(System.in);
String op = "y";
do {
Salary salary = new Salary();
System.out.println("Please Enter Salary for User "
+ salary.getEmpId() + " :");
salary.setSalary(sc.nextDouble());
salary.calculateBonus();
System.out.println(salary);
salaries.add(salary);
System.out.println("Do you want to enter more salaries: ");
op = sc.next();
} while (op.equals("y"));
double totalSalaries = 0;
double totalBonus = 0;
double averageBonus = 0;
int numberOfSalaries = 0;
for (Salary salary : salaries) {
System.out.println("Empid: " + salary.getEmpId() + " Salary: "
+ salary.getSalary() + " Bonus Rate: "
+ salary.getBonusRate() + " Bonus Amount: "
+ salary.getBonusAmount() + " Total Salary: "
+ salary.getTotalSalary());
totalSalaries = totalSalaries + salary.getTotalSalary();
totalBonus = totalBonus + salary.getBonusAmount();
numberOfSalaries = numberOfSalaries + 1;
}
averageBonus = totalBonus / numberOfSalaries;
System.out.println("Total Salaries for all employees: " + totalSalaries
+ " Total Bonuses: " + totalBonus
+ " Average Bonuses for all employees: " + averageBonus);
}
}
The code shall suffice your requirements.
The task is to create different classes using inheritance in creating bank accounts. We then deposit, withdraw and report balances. I have 4 classes:
Superclass: BankAccount
Subclass: Checking Account
Subclass: Savings Account
Method class: BankApp
BankAccount Superclass:
public class BankAccount {
String firstName;
String lastName;
String ssn;
protected float balance;
float withdraw;
float deposit;
long accountNumber;
BankAccount (){
}
BankAccount(String firstName, String lastName, String ssn, float balance){
this.firstName = firstName;
this.lastName = lastName;
this.ssn = ssn;
this.balance = balance;
}
long accountNumber() {
long accountNumber = (long) Math.floor(Math.random() * 9000000000L) + 1000000000L;
return accountNumber;
}
public void deposit(float amount) {
balance = balance + amount;
System.out.println(firstName + " " + lastName + " deposited $" + deposit + ". Current Balance $" + balance);
}
public void withdraw(float amount) {
if (balance >= withdraw) {
balance = balance - amount;
System.out.println(firstName + " " + lastName + " withdrew $" + withdraw + ". Current Balance $" + balance);
}
if (balance < withdraw) {
System.out.println("Unable to withdraw " + amount + " for " + firstName + " " + lastName + " due to insufficient funds.");
}
}
}
Checking Account Subclass:
public class CheckingAccount extends BankAccount {
float amtInterest;
float applyInterest;
String displayBalance;
public CheckingAccount() {
}
public CheckingAccount(String firstName, String lastName, String ssn, float balance) {
super(firstName, lastName, ssn, balance);
System.out.println("Successfully created account for " + firstName + " " + lastName + " " + accountNumber);
System.out.println(firstName + " " + lastName + ", Balance $" + balance);
}
float applyInterest () {
if (balance <= 10000) {
balance = balance * 0.1f;
}
if (balance > 10000) {
balance = 1000 + (balance * 0.02f);
}
return balance;
}
float displayBalance() {
return balance;
}
}
I omitted the SavingsAccount SubClass because I can adjust that class with the help you guys can give me on these two classes.
Output:
Successfully created account for Alin Parker 0 //Not displaying a random account number (1)
Alin Parker, Balance $1000.0
Successfully created account for Mary Jones 0
Mary Jones, Balance $500.0
Successfully created account for John Smith 0
John Smith, Balance $200.0
Alin Parker deposited $0.0. Current Balance $23000.0 //Deposit being calculated but displayed as 0 (2)
Mary Jones deposited $0.0. Current Balance $12500.0
Alin Parker withdrew $0.0. Current Balance $21000.0 //Withdrawal being calculated but displayed as 0 (3)
Mary Jones withdrew $0.0. Current Balance $11500.0
Alin Parker withdrew $0.0. Current Balance $-28580.0 //Should not show negative balance and only notice below (4)
Unable to withdraw 30000.0 for Alin Parker due to insufficient funds
I have outlined my questions above in the output:
1) Randomized 10 digit account number is displaying as 0
2) Deposit amount is being deducted but displaying as 0
3) Withdrawal amount is being deducted but displaying as 0
4) The "insufficient funds" statement should display instead of a negative balance
5) Main method has functions that are not being carried out:
public class BankApp {
public static void main(String[] args) {
CheckingAccount acct1 = new CheckingAccount("Alin", "Parker", "123-45-6789", 1000.0f);
CheckingAccount acct2 = new CheckingAccount("Mary", "Jones", "987-65-4321", 500.0f);
SavingsAccount acct3 = new SavingsAccount("John", "Smith", "1233-45-6789", 200.0f);
acct1.deposit(22000.00f);
acct2.deposit(12000.00f);
acct1.withdraw(2000.00f);
acct2.withdraw(1000.00f);
acct1.applyInterest(); //seems to skip
acct2.applyInterest(); //seems to skip
acct1.displayBalance(); //seems to skip
acct2.displayBalance(); //seems to skip
acct1.withdraw(30000.00f);
}
}
Thank you in advance for your help
The problem is with :
public void withdraw(float amount) {
if (balance >= withdraw) {
balance = balance - amount;
System.out.println(firstName + " " + lastName + " withdrew $" + withdraw + ". Current Balance $" + balance);
}
if (balance < withdraw) {
System.out.println("Unable to withdraw " + amount + " for " + firstName + " " + lastName + " due to insufficient funds.");
}
}
The solution is :
public void withdraw(float amount) {
if (balance >= amount) {
balance = balance - amount;
System.out.println(firstName + " " + lastName + " withdrew $" + amount + ". Current Balance $" + balance);
}
if (balance < amount) {
System.out.println("Unable to withdraw " + amount + " for " + firstName + " " + lastName + " due to insufficient funds.");
}
}
I am supposed to add a toString method to the banckAccount class.
It should return a name separated by a comma and a space. Ex: "Yana" and balance of 3.03 , the call yana.toString() should return the string "Yana, $3.03".
I tried to add:
public String toString() {
return name + ", " + "$"+ balance;
}
It works when I type in:
"user, $90.01"
But when I enter
"Bankrupt Government, -$765432.10"
I keep getting:
"Bankrupt Government, $-765432.1"
Code:
import java.util.*;
public class BankAccount {
String name;
double balance;
public void deposit (double amount ){
balance = balance + amount;
}
public void withdraw ( double amount) {
balance = balance - amount ;
}
}//end of class
Your answer is right here:
return name + ", " + "$"+ balance;
Java simply concatenates the string as you have defined it. So if balance is a negative number, you will get $, followed by a negative number.
If you want it to display the - in the proper place, you can do something like this:
String sign = (balance < 0) ? "-" : "";
System.out.println(name + ", " + sign + "$" + Math.abs(balance));
Your balance is negative so it prints as listed. It needs to be
if(balance < 0){
balance = balance * -1;
return name + ", " + "-$"+ balance;
}
else{
return name + ", " + "$"+ balance;
}
It is quite obvious, what your method toString() is doing. If balance is negative, it is just added to the string with "-" sign after the "$". I would detect, if the balance is positive or not:
private String toString() {
if (balance > 0.0) {
return name + ", " + "$" + balance;
} else {
return name + ", -$" + (balance * (-1));
}
}
Or
private String toString() {
return name + ", " +
balance > 0.0 ? ("$" + balance) : ("-$" + (balance * (-1)));
}
hope this helps run this program
import java.util.*;
import java.io.*;
public class HelloWorld{
public String toString() {
if(balance<0)
{
balance= Math.abs(balance);
return name + ", " +"-"+ "$"+ balance;
}else
{
return name + ", " + "$"+ balance;
}
}
String name="sachin";
double balance=-1000.00;
public void deposit (double amount ){
balance = balance + amount;
}
public void withdraw ( double amount) {
balance = balance - amount ;
}
public static void main(String []args){
// System.out.println("Hello World");
HelloWorld helloWorld = new HelloWorld();
System.out.println(helloWorld.toString());
}
}
This question already has answers here:
How do I print my Java object without getting "SomeType#2f92e0f4"?
(13 answers)
Closed 7 years ago.
BankAccount b0, b1, b2, b3;
b1=new BankAccount();
b2=new BankAccount();
b3=new BankAccount();
for (int i=0; i<3; i++)
{
if (i==0)
b0=b1;
else if (i==1)
b0=b2;
else
b0=b3;
and (what you just saw was part of the demo, below is part of the class stuff)
public String toString(double deposit, double withdraw, double fee, double total) {
String str=name+"'s bank account statement:" + "\nInitial balance: " + balance +
"\nDeposit amount: " + deposit + "\nWithdraw amount: " + withdraw + "\nNumber of transactions: "
+ transac + "\nTotal bank fees: " + fee + "Final monthly balance: " + total;
return str;
and (demo, I haven't included all the code, just because this is still an open assignment.
System.out.println(b0);
I really have no clue why it's not printing the string stuff :(
all of the class (will remove later)
public class BankAccount {
private String name;
private double balance;
private int transac;
public BankAccount() {
balance=0;
}
public void setName(String accountName) {
name=accountName;
}
public void setBalance(double accountBalance) {
balance=accountBalance;
}
public void setTransac(int accountTransac) {
transac=accountTransac;
}
public String getName() {
return name;
}
public double getBalance() {
return balance;
}
public int getTransac() {
return transac;
}
public double getDeposit(double deposit) {
return balance+deposit;
}
public double getWithdraw(double deposit, double withdraw) {
return balance+deposit-withdraw;
}
public double getFee(double fee, int accountTransac, double deposit, double withdraw) {
fee=10;
if (transac<20)
fee+=transac*0.5;
else if (20<=transac && accountTransac<40)
fee+=transac*0.25;
else if (40<=transac && transac<60)
fee+=transac*0.2;
else
fee+=transac*0.1;
if (balance+deposit-withdraw<400)
fee+=15;
return fee;
}
public double finalBalance(double fee, int accountTransac, double deposit, double withdraw) {
double total=balance+deposit-withdraw-fee;
return total;
}
public String toString(double deposit, double withdraw, double fee, double total) {
toString(this.deposit, this.withdraw, this.fee, this.total);
String str=name+"'s bank account statement:" + "\nInitial balance: " + balance +
"\nDeposit amount: " + deposit + "\nWithdraw amount: " + withdraw + "\nNumber of transactions: "
+ transac + "\nTotal bank fees: " + fee + "Final monthly balance: " + total;
return str;
}
}
you should override public String toString() method (without arguments):
if you already have method public String toString(double deposit, double withdraw, double fee, double total) then use this:
class BankAccount {
public String toString() {
toString(this.deposit, this.withdraw, this.fee, this.total);
}
/* .. */
You've overloaded the toString() method, providing a sibling with a different set of arguments.
You want to override the toString() method without arguments.
For example, if all the arguments to your other toString() method were member fields:
public String toString() {
String str=name+"'s bank account statement:" + "\nInitial balance: " + balance +
"\nDeposit amount: " + deposit + "\nWithdraw amount: " + withdraw + "\nNumber of transactions: "
+ transac + "\nTotal bank fees: " + fee + "Final monthly balance: " + total;
return str;
}
The piece of information that the other answers are missing that's important is that when you call System.out.println(b0) the java compiler is automatically inserting a call to .toString() - it's part of the language definition explained here.
Therefore, as said elsewhere, to print out an object you need to override this method.