使用线程池同步库java

ippsafx7  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(271)

我想用java中的线程制作一个简单的银行。但我无法使deposit()、draw()同步。不是一直都有同步的平衡。我在方法名中写了'synchronized'关键字,但它永远不起作用。另外,我在arraylist中创建了“synchronizedlist”(我应该使用arraylist来创建它),但它从来都不起作用。我怎样才能得到适当的平衡?请帮帮我。

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;
    }
}
9vw9lbht

9vw9lbht1#

这里的核心错误是每笔交易都有自己的账户。每个线程都在自己的account示例上获取锁,结果是没有实际的锁在进行。
你需要一个线程之间共享的锁,它们需要尝试修改相同的帐户对象。标记为的示例方法 synchronized 获取烘焙到对象示例中的锁。
使帐户上的余额保持静态是一个肮脏的黑客行为,它会使所有的余额数据最终都在同一个地方(只要您只有一个帐户,它就可以工作),但不能解决同步问题。
(您也可以将account方法更改为静态的,这样可以解决同步问题,因为所有线程都将获取类的锁,并且只有一个类。当然,一旦您需要第二个帐户,它就会停止工作,因此这不是一个很好的解决方案。)
对此进行修改,这样,您就可以跨事务共享同一个account对象,而不是让每个事务都创建自己的帐户。您可以将帐户作为构造函数参数传递到事务中。

相关问题