有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

多线程java线程和互斥

我有以下类别代表银行系统:

作为监视器的类:BankAccount

public class BankAccount 
{
    private boolean isLocked = false;
    private int balance;
    private String name;
    private int nrWithdrawals;
    public  Transaction Transaction;

    public BankAccount()
    {
        this.balance = 300;
        this.name = "Bank Account";
    }

    public synchronized void  withdraw(Transaction tran)
    {
        while(!canWithdraw(tran))
        {
            try
            {  
                wait();
                System.out.println("Not enough money: ");                               
            }
            catch( InterruptedException e) {}
        }

        this.setBalance((this.getBalance() - tran.getBalance()));
        System.out.println("Remaining Balance is: " + this.getBalance());
    }


    public synchronized void depositMoney( )
    {
        while(this.getBalance() + 100 <= this.BankAccountLimit)
        {
            try
            {
                wait();
            }
            catch(InterruptedException e){}
        }

        this.setBalance(this.getBalance() + 100);
        System.out.println("Bank Account balance is: " + this.getBalance());
    }
}

一个名为:User的类(线程)

public class User extends Thread
{   
    private final BankAccount account;
    private ThreadGroup threadGroup;
    private Transaction tran;
    private String bName;
    private String userName;

    public User(BankAccount acc, ThreadGroup group, String name)
    {
        super(group, name);
        this.account = acc
        this.userName = name;
        this.threadGroup = group;
    }

    public void run()
    {
        for(int i = 0; i< 3; i++)
        {
            Transaction transaction = new Transaction(70);
            account.withdraw(tran);

            System.out.println(this.getUserName() + " is using the bankaccount");
            try
            {  
                sleep(2000);     
            }
            catch(InterruptedException e){}
        } 
    }
}

一个名为Manager的类(线程)

public class Manager extends Thread
{
    private final BankAccount account;
    private ThreadGroup threadGroup;
    private String managerName;

    public Manager(BankAccount acc, ThreadGroup tgroup, String name)
    {
        account = acc;
        threadGroup = tgroup;
        managerName = name;
    }

    public void run()
    {
        for(int i = 0; i < 3; i++)
        {
            account.depositMoney();
            try
            {
                sleep(100);
                System.out.println("trying....");
            }
        }
        catch(InterruptedException e){} 
    }  
}

这是一个主要的方法

public static void main(String[] args) 
{
    ThreadGroup users = new ThreadGroup("Users");
    ThreadGroup managers = new ThreadGroup("Managers");

    BankAccount account = new BankAccount();
    User user1 = new User(account, users, "User1");
    User user2 = new User(account, users, "User2");
    Manager manager = new Manager(account, managers, "Manager1");   
    user1.start();
    user2.start();
    manager.start();
}

我希望实现的目标如下:

用户1或用户2开始取款(每个人尝试多次)。假设user1首先启动

如果没有足够的钱,等待经理存入(尝试存入三次或类似的次数)一些钱,然后用户1继续取款,然后在他完成后,用户2开始取款

我的问题是: 如何确保user1或user2是第一个运行的线程。 是否可以让一个线程等待,执行另一个线程并恢复正在等待的线程?(让用户1等待,执行管理器,然后恢复用户1,然后执行剩余的用户?)


共 (2) 个答案

  1. # 1 楼答案

    Is it posible make a thread wait, execute another and resume the one that is waiting

    对。你所指的是生产者-消费者问题的典型案例

    您可以通过使用synchronized关键字来使用显式同步。使用wait方法使线程释放其锁,并使用notify方法通知线程锁现在可用

    您也可以使用ReenterantLock

  2. # 2 楼答案

    你在这里很少犯错误

    1. 你的天平不是螺纹安全的。两个线程可以在Draw和depositMoney方法中更改它。因此,您可以使用互斥锁,如bot所述的Reentrantlock
    2. 如果你的死刑以wait()结束,要么取款,要么存钱,那么就没有办法逃脱了。为了避免这种情况,您可以在每次取款或存款后调用notifyAll()

    这是带有建议修改的示例代码

    public class BankAccount
        {
            private boolean isLocked = false;
            private int balance;
            private String name;
            private int nrWithdrawals;
            public  Transaction Transaction;
            private ReentrantLock lock = new ReentrantLock();
    
            public BankAccount()
            {
                this.balance = 300;
                this.name = "Bank Account";
            }
    
            public synchronized void Withdraw(Transaction tran)
            {
                lock.lock();
                while(!CanWithdraw(tran))
                {
                    try
                    {
                        lock.unlock();
                        System.out.println("Not enough money. Waiting for manager to deposit");
                        wait();
                        lock.lock();
    
                    }
                    catch( InterruptedException e) {}
                }
                this.setBalance((this.getBalance() - tran.getBalance()));
                notifyAll();
    
                System.out.println("Remaining Balance is: " + this.getBalance());
                lock.unlock();
            }
    
    
            public synchronized void depositMoney( )
            {
                lock.lock();
                while(this.getBalance() + 100 <= this.BankAccountLimit)
                {
                    try
                    {
                        lock.unlock();
                        wait();
                        lock.lock();
                    }
                    catch(InterruptedException e){}
                }
    
    
                this.setBalance(this.getBalance() + 100);
                notifyAll();
                System.out.println("Bank Account balance is: " + this.getBalance());
                lock.unlock();
            }
        }