线程池中的问题

时间:2017-02-19 03:41:53

标签: java multithreading threadpool

注意:线程号1 =所有者1 - >执行10笔交易
      线程号2 =所有者2 - >执行10笔交易

问题:在输出中:

Owner: 1   transaction: 2
Owner: 1   transaction: 1
credit: $46 credit: $30  balance: $146
 balance: $130

在交易2之后,余额应为176美元。线程池中必定存在一些问题。我尝试了很多,但无法达到理想的解决方案。任何帮助都会很明显。

输出

     run:
    Initial Balance: $100
    Owner: 1   transaction: 1
    Owner: 1   transaction: 2
    credit: $46 credit: $30  balance: $146
     balance: $130
    Owner: 2   transaction: 1
    Owner: 2   transaction: 2
     debit: $46 debit: $30 Debit Done    Debit Done  Balance: $100 Balance: $100
    Owner: 1   transaction: 3
    credit: $75 Owner: 1   transaction: 4
     balance: $175
    credit: $47 Owner: 2   transaction: 3
     balance: $147
    Owner: 2   transaction: 4
     debit: $47 debit: $75 Debit Done    Debit Done  Balance: $100 Balance: $100
    Owner: 1   transaction: 5
    credit: $57 Owner: 1   transaction: 6
     balance: $157
    credit: $13 Owner: 2   transaction: 5
     balance: $113
     debit: $57 Debit Done  Owner: 2   transaction: 6
     Balance: $100 debit: $13 Debit Done     Balance: $100 Owner: 1   transaction: 7
    credit: $84 Owner: 1   transaction: 8
     balance: $184
    credit: $95 Owner: 2   transaction: 7
     balance: $195
    Owner: 2   transaction: 8
     debit: $84 Debit Done   debit: $95 Debit Done   Balance: $100 Balance: $100
    Owner: 1   transaction: 10    credit: $96    balance: $196
    Owner: 1   transaction: 9
    Owner: 2   transaction: 10
    credit: $20  debit: $96 Debit Done   balance: $120
     Balance: $100
    Owner: 2   transaction: 9
    debit: $20 Debit Done    Balance: $100B

银行

public class Bank{

private BankAccount bankAccount = new BankAccount(100);

public void displayInitialBalance(){
    System.out.println("Initial Balance:"+getBankAccount());
}

/**
 * @return the bankAccount
 */
public BankAccount getBankAccount() {
    return bankAccount;
}

/**
 * @param bankAccount the bankAccount to set
 */
public void setBankAccount(BankAccount bankAccount) {
    this.bankAccount = bankAccount;
}

public static void main(String[] args){
    BankAccount bankAccount = new BankAccount(100);
    System.out.println("Initial Balance: $"+bankAccount.getCurrentBalance());
    ExecutorService executorService = Executors.newFixedThreadPool(2);
    for(int count = 1; count<=10; count++){
        Runnable runnable = new Owner(count);
        executorService.execute(runnable);
    }
    executorService.shutdown();
    while(!executorService.isTerminated()){
    }
    System.out.println("All Transactions Done");
}

}


的BankAccount

public class BankAccount {

private int currentBalance;

public BankAccount(int initialBalance){
    this.currentBalance = initialBalance;
}

synchronized public void credit(int amount){
    setCurrentBalance(currentBalance + amount);
    System.out.print("credit: $"+amount+"\t");
    System.out.println(" balance: $"+getCurrentBalance());
}

synchronized public void debit(int amount){
    if(getCurrentBalance() >= amount){
        setCurrentBalance(currentBalance - amount);
        System.out.print(" debit: $"+amount);
        System.out.print(" Debit Done" +"\t");                
        System.out.print(" Balance: $"+getCurrentBalance());            
    }
    else{
        System.out.print("Insufficient Balance"+"\t");
        System.out.println("Balance: $"+getCurrentBalance());
    }
}

/**
 * @return the currentBalance
 */
public int getCurrentBalance() {
    return currentBalance;
}

/**
 * @param currentBalance the currentBalance to set
 */
public void setCurrentBalance(int currentBalance) {
    this.currentBalance = currentBalance;
}
}    


所有者

public class Owner implements Runnable{

public int transactionCount = 0;
public int amount = 0;

private BankAccount bankAccount = new  BankAccount(100);

public Owner(int transactionCycle){
    this.transactionCount = transactionCycle;
}

public Owner(int transactionId, BankAccount bankAccount){
    this.bankAccount = bankAccount;
    this.transactionCount = transactionId;
}

@Override
public void run() {
   try{
       amount = (int)(Math.random() * 100 + 10);
       Thread call = new Thread();
       call.start();
       Thread.currentThread().setName("Owner: 1 "+"  transaction: "+transactionCount);
       (transactionCount)++;
       System.out.println(Thread.currentThread().getName());
       getBankAccount().credit(amount);
       Thread.currentThread().setName("Owner: 2 "+"  transaction: "+ --(transactionCount));
       (transactionCount)++;
       System.out.println(Thread.currentThread().getName());
       getBankAccount().debit(amount);
   }catch(UnsupportedOperationException e){
       e.printStackTrace();
   } 

}

/**
 * @return the bankAccount
 */
public BankAccount getBankAccount() {
    return bankAccount;
}

/**
 * @param bankAccount the bankAccount to set
 */
public void setBankAccount(BankAccount bankAccount) {
    this.bankAccount = bankAccount;
}

}

2 个答案:

答案 0 :(得分:0)

您正在Bank.main()中创建新的所有者实例,而不传递BankAccount,因此每个所有者对象都在不同的BankAccount实例上运行

答案 1 :(得分:0)

完成了很多尝试,并获得了所需的输出

已完成的更改

的BankAccount

private int currentBalance = 0; // set default value of int
public void credit(int amount){
    System.out.print(" credit: $"+amount+"\t");
}

public Boolean debit(int amount){
    if(getCurrentBalance() >= amount){
        return true;
    }
    else
        return false;
}

银行
How to wait for all threads to finish, using ExecutorService?

主要方法的内部循环

Runnable runnable = new Owner(id,bankAccount);
bankAccount.getCurrentBalance(); // To print each thread transaction balance
try {
        executorService.awaitTermination(Long.MAX_VALUE,  TimeUnit.NANOSECONDS); // instead of Terminate use awaitTermination method for each thread 
    } catch (InterruptedException e) {
        e.printStackTrace();
    }    

所有者

try{
       amount = (int)(Math.random() * 100 + 10);
       Thread.currentThread().setName(" Owner: 1 "+"  transaction: "+transactionCount);
       (transactionCount)++;
       System.out.print(Thread.currentThread().getName()+"\n");
       getBankAccount().credit(amount);
       bankAccount.setCurrentBalance(getBankAccount().getCurrentBalance() + amount);
       System.out.print("Balance: $"+bankAccount.getCurrentBalance());
       amount = (int)(Math.random() * 100 + 10);
       Thread.currentThread().setName(" Owner: 2 "+"  transaction: "+ --(transactionCount));
       System.out.print(Thread.currentThread().getName()+"\n");
       (transactionCount)++;
       getBankAccount().getCurrentBalance();
       Boolean isDebit = getBankAccount().debit(amount);
       if(isDebit){
           try {
                bankAccount.setCurrentBalance(getBankAccount().getCurrentBalance() - amount);
                System.out.println(" debit: $"+amount);
                System.out.print(" Debit Done" +"\t");
                System.out.println(" Balance: $"+bankAccount.getCurrentBalance());
           } catch (SecurityException ex) {
                Logger.getLogger(Owner.class.getName()).log(Level.SEVERE, null, ex);
           }
        }else{
                System.out.println("Insufficeint Balance");
        }

   }catch(UnsupportedOperationException e){
       e.printStackTrace();
   }