使用线程池同步库java

使用线程池同步库java,java,multithreading,synchronized,Java,Multithreading,Synchronized,我想用Java中的线程创建一个简单的银行。 但我无法使存款()和取款()同步。 并非一直都有同步平衡。我写 方法名称中的“synchronized”关键字,但它永远不起作用。 此外,我在我的ArrayList中创建了“synchronizedList”(我应该使用ArrayList来创建),但它从来都不起作用。我怎样才能获得适当的平衡?请帮帮我 import java.security.SecureRandom; public class Transaction implements Runn

我想用Java中的线程创建一个简单的银行。 但我无法使存款()和取款()同步。 并非一直都有同步平衡。我写 方法名称中的“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;
    }
}
导入java.security.SecureRandom;
公共类事务实现可运行{
私有静态最终SecureRandom生成器=新SecureRandom();
private final int sleepTime;//线程的随机睡眠时间
私有字符串事务;
私人整数金额;
私有静态整数平衡;
私人账户=新账户();
公共事务(字符串事务,整数金额){
this.transaction=交易;
这个。金额=金额;
睡眠时间=发电机。下一次更新(2000年);
}
@凌驾
公开募捐{
//TODO自动生成的方法存根
试一试{
如果(交易=“存款”){
余额=账户。存款(金额);
}否则如果(交易==“撤销”){
余额=账户提取(金额);
}
系统输出打印项次(“[”+交易+“]金额:“+金额+”余额:“+余额”);
睡眠(睡眠时间);
}捕捉(中断异常e){
e、 printStackTrace();
Thread.currentThread().interrupt();//重新中断线程
}
}
}
导入java.util.ArrayList;
导入java.util.Collections;
导入java.util.List;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
公开课会计考试{
公共静态void main(字符串[]args){
//TODO自动生成的方法存根
//创建ArrayList
List john=Collections.synchronizedList(新的ArrayList());
//添加事务对象
john.add(新交易(“存款”,1000));
john.add(新交易(“撤销”,500));
john.add(新交易(“撤销”,200));
john.add(新交易(“存款”,3000));
//执行线程池
ExecutorService ExecutorService=Executors.newCachedThreadPool();
//启动交易

对于(inti=0;i来说,这里的核心错误是每个事务都有自己的帐户。每个线程都在自己的帐户实例上获取锁,结果是没有实际的锁定

您需要线程之间共享的锁,它们需要尝试修改同一帐户对象。标记为
synchronized
的实例方法获取烘焙到对象实例中的锁

使帐户余额保持静态是一个肮脏的黑客行为,它会使所有余额数据最终都位于同一个位置(只要您只有一个帐户,它就可以工作),但不会解决同步问题

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

重做此操作,这样,您就可以跨事务共享同一帐户对象,而不是让每个事务创建自己的帐户。您可以将帐户作为构造函数参数传递到事务中