@@ -20,9 +20,9 @@ package org.apache.spark.executor
20
20
import java .net .URL
21
21
import java .nio .ByteBuffer
22
22
import java .util .Locale
23
+ import java .util .concurrent .ConcurrentHashMap
23
24
import java .util .concurrent .atomic .AtomicBoolean
24
25
25
- import scala .collection .mutable
26
26
import scala .util .{Failure , Success }
27
27
import scala .util .control .NonFatal
28
28
@@ -71,9 +71,12 @@ private[spark] class CoarseGrainedExecutorBackend(
71
71
/**
72
72
* Map each taskId to the information about the resource allocated to it, Please refer to
73
73
* [[ResourceInformation ]] for specifics.
74
+ * CHM is used to ensure thread-safety (https://issues.apache.org/jira/browse/SPARK-45227)
74
75
* Exposed for testing only.
75
76
*/
76
- private [executor] val taskResources = new mutable.HashMap [Long , Map [String , ResourceInformation ]]
77
+ private [executor] val taskResources = new ConcurrentHashMap [
78
+ Long , Map [String , ResourceInformation ]
79
+ ]
77
80
78
81
private var decommissioned = false
79
82
@@ -186,7 +189,7 @@ private[spark] class CoarseGrainedExecutorBackend(
186
189
} else {
187
190
val taskDesc = TaskDescription .decode(data.value)
188
191
logInfo(" Got assigned task " + taskDesc.taskId)
189
- taskResources(taskDesc.taskId) = taskDesc.resources
192
+ taskResources.put (taskDesc.taskId, taskDesc.resources)
190
193
executor.launchTask(this , taskDesc)
191
194
}
192
195
@@ -266,7 +269,7 @@ private[spark] class CoarseGrainedExecutorBackend(
266
269
}
267
270
268
271
override def statusUpdate (taskId : Long , state : TaskState , data : ByteBuffer ): Unit = {
269
- val resources = taskResources.getOrElse (taskId, Map .empty[String , ResourceInformation ])
272
+ val resources = taskResources.getOrDefault (taskId, Map .empty[String , ResourceInformation ])
270
273
val cpus = executor.runningTasks.get(taskId).taskDescription.cpus
271
274
val msg = StatusUpdate (executorId, taskId, state, data, cpus, resources)
272
275
if (TaskState .isFinished(state)) {
0 commit comments