From 32dc6b5aa956786cbc16ffb97ce5becbfa52ee80 Mon Sep 17 00:00:00 2001 From: Dmitry Kichinsky Date: Sat, 20 May 2023 21:05:13 +0200 Subject: [PATCH] [maven] IDEA-313767 MavenProjectsManager: replace synchronized with concurrent collections GitOrigin-RevId: 59b4228c51e60d1a15cc31c9654eebc2ac20b47d --- .../maven/project/MavenProjectsManager.java | 79 ++++++++----------- 1 file changed, 33 insertions(+), 46 deletions(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManager.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManager.java index 35343121fa5b..e2e6f5a651f3 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManager.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManager.java @@ -76,7 +76,9 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.ReentrantLock; import java.util.function.Consumer; @@ -104,11 +106,10 @@ public class MavenProjectsManager extends MavenSimpleProjectComponent private MavenProjectsProcessor myPostProcessor; private MavenMergingUpdateQueue myImportingQueue; - private final Object myImportingDataLock = new Object(); - private final Map myProjectsToImport = new LinkedHashMap<>(); - private final Set myProjectsToResolve = new LinkedHashSet<>(); + private final ConcurrentHashMap myProjectsToImport = new ConcurrentHashMap<>(); + private final Set myProjectsToResolve = ConcurrentHashMap.newKeySet(); - private boolean myImportModuleGroupsRequired = false; + private final AtomicBoolean myImportModuleGroupsRequired = new AtomicBoolean(false); private final EventDispatcher myProjectsTreeDispatcher = EventDispatcher.create(MavenProjectsTree.Listener.class); @@ -118,7 +119,7 @@ public class MavenProjectsManager extends MavenSimpleProjectComponent private MavenWorkspaceSettings myWorkspaceSettings; - private volatile MavenSyncConsole mySyncConsole; + private final AtomicReference mySyncConsole = new AtomicReference<>(); private final MavenMergingUpdateQueue mySaveQueue; private static final int SAVE_DELAY = 1000; private Module myPreviewModule; @@ -175,7 +176,7 @@ public class MavenProjectsManager extends MavenSimpleProjectComponent @Override public void dispose() { - mySyncConsole = null; + mySyncConsole.set(null); myManagerListeners.clear(); } @@ -347,11 +348,11 @@ public class MavenProjectsManager extends MavenSimpleProjectComponent }); } - public synchronized MavenSyncConsole getSyncConsole() { - if (mySyncConsole == null) { - mySyncConsole = new MavenSyncConsole(myProject); + public MavenSyncConsole getSyncConsole() { + if (null == mySyncConsole.get()) { + mySyncConsole.compareAndSet(null, new MavenSyncConsole(myProject)); } - return mySyncConsole; + return mySyncConsole.get(); } @NotNull @@ -1058,11 +1059,8 @@ public class MavenProjectsManager extends MavenSimpleProjectComponent private AsyncPromise> scheduleResolve() { final AsyncPromise> result = new AsyncPromise<>(); runWhenFullyOpen(() -> { - LinkedHashSet toResolve; - synchronized (myImportingDataLock) { - toResolve = new LinkedHashSet<>(myProjectsToResolve); - myProjectsToResolve.clear(); - } + LinkedHashSet toResolve = new LinkedHashSet<>(myProjectsToResolve); + myProjectsToResolve.removeAll(toResolve); if (toResolve.isEmpty()) { result.setResult(Collections.emptyList()); myProject.getMessageBus().syncPublisher(MavenImportListener.TOPIC) @@ -1158,9 +1156,7 @@ public class MavenProjectsManager extends MavenSimpleProjectComponent } private void scheduleImportSettings(boolean importModuleGroupsRequired) { - synchronized (myImportingDataLock) { - myImportModuleGroupsRequired = importModuleGroupsRequired; - } + myImportModuleGroupsRequired.set(importModuleGroupsRequired); scheduleImportChangedProjects(); } @@ -1181,11 +1177,11 @@ public class MavenProjectsManager extends MavenSimpleProjectComponent runWhenFullyOpen(() -> myImportingQueue.queue(new Update(this) { @Override public void run() { - synchronized (myImportingDataLock) { - for (MavenProject project : getProjectsTree().getProjects()) { - myProjectsToImport.put(project, MavenProjectChanges.ALL); - } - } + var projectsToImport = ContainerUtil.map2Map( + getProjectsTree().getProjects(), + project -> new Pair<>(project, MavenProjectChanges.ALL) + ); + myProjectsToImport.putAll(projectsToImport); importProjects(); fireProjectImportCompleted(); } @@ -1210,26 +1206,20 @@ public class MavenProjectsManager extends MavenSimpleProjectComponent } private void scheduleForNextImport(Collection> projectsWithChanges) { - synchronized (myImportingDataLock) { - for (Pair each : projectsWithChanges) { - myProjectsToImport.compute(each.first, (__, previousChanges) -> - previousChanges == null ? each.second : MavenProjectChangesBuilder.merged(each.second, previousChanges) - ); - } + for (Pair each : projectsWithChanges) { + myProjectsToImport.compute(each.first, (__, previousChanges) -> + previousChanges == null ? each.second : MavenProjectChangesBuilder.merged(each.second, previousChanges) + ); } } private void scheduleForNextResolve(Collection projects) { - synchronized (myImportingDataLock) { - myProjectsToResolve.addAll(projects); - } + myProjectsToResolve.addAll(projects); } public boolean hasScheduledProjects() { if (!isInitialized()) return false; - synchronized (myImportingDataLock) { - return !myProjectsToImport.isEmpty() || !myProjectsToResolve.isEmpty(); - } + return !myProjectsToImport.isEmpty() || !myProjectsToResolve.isEmpty(); } @TestOnly @@ -1277,11 +1267,9 @@ public class MavenProjectsManager extends MavenSimpleProjectComponent } private void unscheduleAllTasks(List projects) { - for (MavenProject each : projects) { - synchronized (myImportingDataLock) { - myProjectsToImport.remove(each); - myProjectsToResolve.remove(each); - } + for (MavenProject project : projects) { + myProjectsToImport.remove(project); + myProjectsToResolve.remove(project); } } @@ -1335,12 +1323,11 @@ public class MavenProjectsManager extends MavenSimpleProjectComponent public List importProjects(IdeModifiableModelsProvider modelsProvider) { Map projectsToImportWithChanges; boolean importModuleGroupsRequired; - synchronized (myImportingDataLock) { - projectsToImportWithChanges = Collections.unmodifiableMap(new LinkedHashMap<>(myProjectsToImport)); - myProjectsToImport.clear(); - importModuleGroupsRequired = myImportModuleGroupsRequired; - myImportModuleGroupsRequired = false; - } + + projectsToImportWithChanges = Collections.unmodifiableMap(new LinkedHashMap<>(myProjectsToImport)); + projectsToImportWithChanges.forEach(myProjectsToImport::remove); + + importModuleGroupsRequired = myImportModuleGroupsRequired.getAndSet(false); return new MavenProjectsManagerImporter( modelsProvider,