java—使用线程安全方法从类中的多个方法填充集合或Map

gopyfrb3  于 2021-07-07  发布在  Java
关注(0)|答案(1)|浏览(361)

请建议解决以下问题的最佳方法:
我有一个java类,如下所示:

@Service
public class ServiceAImpl {

    private final Set<String> someSet = new HashSet<>();
    private final List<Record> someList = new ArrayList<>();
    private final Map<String, String> someMap = new HashMap<>();

   //Loads XML as a document
   public Optional<Document> readXML(Document xmlDoc){

   }

   //reads the root node and triggers the recursive extraction of the XML data
   public List<Record> extractRootNodeAndTriggersRecursive(){
       extractXMLRecursively(elt);

   }

   //recursively read hierarchical data in the XML
   public SomeObject extractXMLRecursively(Element elt){

   }

   public SomeObject createReportFromTheMapOrList(){

   }

}

我知道示例成员(或列表/Map)不是线程安全的。
如果列表/集合/Map需要通过对同一类中定义的多个方法的多个调用来更新或填充,那么实现这种逻辑的最佳方法是什么。
因此,在另一个调用类(主springboot应用程序)中,我将获得list/set/map,以便在填充之后处理它们。
我认为上面的代码可能适用于一个独立的应用程序,作为一个时间表,每周运行一次,即并发性不会是一个问题。但是,如果服务暴露在多个线程中,我应该如何对其进行返工?
有人遇到过这种情况吗?
任何意见或提示或参考将不胜感激。
谢谢。

bjg7j2ky

bjg7j2ky1#

你可以用 ReentrantLock :

import java.util.concurrent.locks.ReentrantLock;

@Service
public class ServiceAImpl {

    private final Set<String> setNoDuplicateLabelsAllowed = new HashSet<>();
    private final Set<String> someSet = new HashSet<>();

    private final ReentrantLock lock = new ReentrantLock();

   //Loads XML as a document
   public Optional<Document> readXML(Document xmlDoc){
       lock.lock();
       try {
           // modify your collections safely here
       } finally {
           lock.unlock();
       }
   }

   //reads the root node and triggers the recursive extraction of the XML data
   public List<Record> extractRootNodeAndTriggersRecursive(){
       lock.lock();
       try {
           // modify your collections safely here
       } finally {
           lock.unlock();
       }
   }

   //recursively read hierarchical data in the XML
   public SomeObject extractXMLRecursively(Element elt){
       lock.lock();
       try {
           // same here, etc.
       } finally {
           lock.unlock();
       }
   }

注意,在每个方法中都需要使用相同的锁。这保证只有一个线程可以在特定时刻更改集合。除非锁被释放,否则所有其他线程都将被阻塞,无论它们尝试以何种特定方法获取该锁。

相关问题