繁体   English   中英

同步2种方法

[英]Synchronize 2 methods

public class ActionForm {
       private Account temporaryAccount = null;
       private Document document;

       /**
       * Save document from another thread that do not have a SecurityContext
       */
       public void saveByAccount(Account account) { 
           this.temporaryAccount = account;
           save();
           this.temporaryAccount = null;
       }

       /**
       * Save document to DB. 
       * I can not change the signature of this method.
       */
       public synchronized void save() {

          //get an account from shared variable or from SecurityContext
           Account account = null;
           Account temporaryAccount = this.temporaryAccount;
           if (temporaryAccount == null) {
               account = SecurityContextWrapper.getAccount();
           } else {
               account = temporaryAccount;
           }

        //save in DB
        saveDocumentInDB(account, document);
    }
}

线程类型1 :用户可以单击“保存”按钮,在这种情况下,方法save()将直接调用。 我从SecurityContext获得帐户。

线程类型2 :用户启动后台进程。 我保存他/她的帐户,然后启动新线程:

final Account account = SecurityContextWrapper.getAccount();
new Thread(new Runnable() {
    public void run() {
        ...//do smth
        saveByAccount(account);
    }
}).start();

问题 :可以更改变量this.temporaryAccount-在调用saveByAccount()和save()之间。 您知道同步这些方法的正确方法吗?

解决此问题的最佳方法是将帐户发送给每个方法作为参数。 封装始终是一个不错的功能,您应该为之努力。 这样,当您需要并行处理时,就不会遇到这种麻烦。

考虑到您无法更改方法签名的评论,建议您在开始使用共享变量之前先使用信号灯。

您可以使用以下代码在类级别创建信号量:

private final Semaphore available = new Semaphore(1, true);

在尝试更改或使用共享变量之前,每种方法都必须调用available.acquire(); 如果信号量正在使用中,这将阻止(因为您只有一个许可,如构造函数调用中所定义),但是如果它是免费的,则它将许可数量减少一个并继续。

完成依赖共享变量的处理后,每个方法应调用available.release(); 然后,等待服务的其他方法之一将获取信号量并继续。

不过,我强烈建议您花些时间重构代码。 全局变量和类变量是“代码异味”,并且将来可能导致错误。 花费在此重构上的时间将在将来带来回报。 此类讨论可在出色的书籍中找到,例如“代码完成”和“清洁代码”。 必须阅读它们,并为我们,程序员提供许多有关代码质量的见解。

我希望这有帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM