开发者社区> 问答> 正文

为什么要用static修饰Lock对象

import java.util.concurrent.*;
import java.util.concurrent.locks.*;

import java_Thread.AccountWithSyncUsingLock.Account;

public class ThreadCooperation {
    private static Account account = new Account();
    
    public static void main(String[] args){
        ExecutorService executor = Executors.newFixedThreadPool(2);
        executor.execute(new DepositTask());
        executor.execute(new WithdrawTask());
        executor.shutdown();
        
        System.out.println("Thread 1\t\tThread 2\t\tBalance");
    }
    
    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();
        private static Condition newDeposit = lock.newCondition();
        private int balance = 0;
        
        public int getBalance(){
            return balance;
        }
        
        public void withdraw(int amount){
            lock.lock();
            try{
                while(balance < amount){
                    System.out.println("\t\t\tWait for a deposit");
                    newDeposit.await();
                }
                balance -=amount;
                System.out.println("\t\t\tWithdraw "+ amount+"\t\t" + getBalance());
            }
            catch(InterruptedException ex){
                ex.printStackTrace();
            }
            finally{
                lock.unlock();
            }
        }
        
        public void deposit(int amount){
            lock.lock();
            try{
                balance += amount;
                System.out.println("Deposit "+ amount + "\t\t\t\t\t" + getBalance());
                
                newDeposit.signalAll();
            }
            finally{
                lock.unlock();
            }
        }
    }
}

为什么声明Lock时要用static?这个例子中只创建了一个Account实例,但假如有多个Account实例的话,按道理它们之间应该是互不干扰的,但是Lock对象声明为类变量的话是不是逻辑就不对了?

展开
收起
蛮大人123 2016-03-11 10:03:17 2685 0
2 条回答
写回答
取消 提交回答
  • 我也觉得这个 static 并非必须。lock 的作用域定义在什么范围,这个根据业务逻辑的需要来定。在楼主的例子中,lock 被声明为静态的,意味着不论访问哪个 Account 对象,都会被全局的同步;如果去掉 static,就意味着有多少个 Account 对象就会有多少个 lock,访问不同的 Account 对象的线程之间不会互相干扰。
    2019-07-17 18:58:29
    赞同 展开评论 打赏
  • 我说我不帅他们就打我,还说我虚伪

    从整体的代码来说这里的static是多余的,因为ThreadCooperation中的Account对象是static的,而且Account中的balance是非static的,所以如果想要达成代码中的效果,其实Lock和Condition前面的static反而会造成误导。

    2019-07-17 18:58:29
    赞同 展开评论 打赏
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载