【问题标题】:Using thread pool synchronization bank java使用线程池同步银行java
【发布时间】:2020-11-25 18:49:23
【问题描述】:

我想用 Java 中的线程创建一个简单的银行。 但是我不能让 deposit(),withdraw() 同步。 始终没有同步平衡。我写的 方法名称中的“同步”关键字,但它永远不会起作用。 另外,我在我的 ArrayList 中制作了“synchronizedList”(我应该使用数组列表来制作它),但它永远不会起作用。我怎样才能获得适当的平衡?请帮帮我。

import java.security.SecureRandom;

public class Transaction implements Runnable {
    
    private static final SecureRandom generator = new SecureRandom();
    private final int sleepTime; // random sleep time for thread
    private String transaction;
    private int amount;
    private static int balance;
    private Account account = new Account();
    
    public Transaction (String transaction, int amount) {
        this.transaction = transaction;
        this.amount = amount;
        sleepTime = generator.nextInt(2000); 
    }
    
    @Override
    public void run() {
        // TODO Auto-generated method stub
        try {
            if(transaction == "deposit") {
                balance = account.deposit(amount);

            } else if (transaction == "withdraw") {
                balance = account.withdraw(amount);
            }
            
            System.out.println("[" + transaction + "] amount : " + amount +" balance : " + balance);
            Thread.sleep(sleepTime);
            
        }catch (InterruptedException e) {
            e.printStackTrace();
             Thread.currentThread().interrupt(); // re-interrupt the thread
        }

    }

}

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class AccountTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        
        // create ArrayList
        List<Transaction> john = Collections.synchronizedList(new ArrayList<>());
        
        // add Transaction objects
        john.add(new Transaction("deposit", 1000));
        john.add(new Transaction("withdraw", 500));
        john.add(new Transaction("withdraw", 200));
        john.add(new Transaction("deposit", 3000));

        // execute Thread Pool
        ExecutorService executorService = Executors.newCachedThreadPool();
        
        // start transactions
        for(int i=0; i<john.size(); i++) {
            executorService.execute(john.get(i)); 
        }
        
        // shut down Thread Pool
    }
}

public class Account {
// deposit withdraw
    private static int balance;
    
    public synchronized int deposit(int amount) {
        balance += amount;
        return balance;
    }
    
    public synchronized int withdraw(int amount) {
        balance -= amount;
        return balance;
    }
}

【问题讨论】:

    标签: java multithreading synchronized


    【解决方案1】:

    这里的核心错误是每个交易都有自己的帐户。每个线程都在自己的 Account 实例上获取锁,结果实际上并没有发生锁定。

    你需要一个在线程之间共享的锁,它们需要尝试修改同一个 Account 对象。标有synchronized 的实例方法获取一个嵌入到对象实例中的锁。

    将帐户上的余额设为静态是一种肮脏的黑客行为,它会使所有余额数据最终都放在同一个位置(仅当您只有一个帐户时才有效),但不能解决同步问题。

    (您也可以将 Account 方法更改为静态方法,这将解决同步问题,因为所有线程都将获取类上的锁,并且只有一个类。但是当然,一旦您需要第二个帐户,它就会停止工作,因此这不是一个很好的解决方案。)

    重新进行此操作,这样您就无需让每个 Transaction 创建自己的帐户,而是在 Transactions 之间共享相同的 Account 对象。您可以将 Account 作为构造函数参数传递给 Transaction。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多