首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java多线程锁不能正常工作

Java多线程锁不能正常工作
EN

Stack Overflow用户
提问于 2020-08-17 14:18:00
回答 1查看 112关注 0票数 0

整个方案是:

代码语言:javascript
复制
import java.util.concurrent.*;
import java.util.concurrent.locks.*;

public class AccountWithConditionsUser {
    private static Account account = new Account();
    public static void main(String[] args) {
        System.out.println("Thread 1\t\tThread 2\t\tBalance");
        ExecutorService executor = Executors.newFixedThreadPool(2);
        executor.execute(new DepositTask());
        executor.execute(new WithdrawTask());
        executor.shutdown();
        while(!executor.isShutdown()) {
        }
    }
    public static class DepositTask implements Runnable{
        public void run() {
            try {
                while(true) {
                    account.deposit((int)(Math.random()* 10)+ 1);
                    Thread.sleep(1000);
                }
            }
            catch(InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }
    
    public static class WithdrawTask implements Runnable{
        public void run() {
            while(true) {
                account.withdraw((int)(Math.random() * 10) + 1);
            }
        }
    }
    
    private static class Account{
        private static Lock lock = new ReentrantLock(true);
        private static Condition newDeposit = lock.newCondition();
        
        private int balance = 0;
        public int getBalance() {
            return balance;
        }
        
        public void withdraw(int amount) {
            lock.lock();
            System.out.println("->Withdraw Obtained Lock");
            try {
                while(balance < amount) {
                    System.out.println("\t\t\tWait for deposit");
                    newDeposit.await();
                }
                balance-=amount;
                System.out.println("\t\t\tWithdraw "+ amount + "\t\t" + getBalance());
            }
            catch(Exception e) {
                e.printStackTrace();
            }
            finally {
                System.out.println("->Withdraw Released Lock");
                lock.unlock();
                
            }
            
        }
        
        public void deposit(int amount) {
            lock.lock();
            System.out.println("->Deposit Obtained Lock");
            try {
                balance+=amount;
                System.out.println("Deposit "+ amount + "\t\t\t\t\t" + getBalance());
                newDeposit.signalAll();
            }
            catch(Exception e) {
                e.printStackTrace();
            }
            finally {
                System.out.println("->Deposit Released Lock");
                lock.unlock();
            }
        }
    }
}

我为这个代码获得的输出的示例部分是:

.

.

取出释放锁

取用锁

等待存款

存款获得锁

交存9 13

存款释放锁

撤回9 4

取出释放锁

.

.

这里的问题是,存款螺纹如何获得一个又一个窗口的锁。它不是应该是,一旦一个锁是获得,它不能得到任何其他线程!还是因为信号的方法?有人能解释一下输出是怎么来的吗?(预先谢谢:)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-08-17 14:22:55

Withdraw获得锁后,它会检查是否有足够的余额。如果没有,则调用newdeposit.await,这将释放锁,以便等待同一锁的其他线程能够进入。这似乎是发生了什么:Withdraw输入了if-块,开始等待,Deposit线程进来并存入了一个金额,唤醒了Withdraw,这样它就可以继续更新的数量了。一旦收到通知,await将锁定并返回,因此Withdraw将继续执行已获得的锁。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63452766

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档