9292import java .util .NavigableMap ;
9393import java .util .Stack ;
9494import java .util .TreeMap ;
95+ import java .util .concurrent .ConcurrentHashMap ;
9596import java .util .concurrent .CopyOnWriteArrayList ;
9697import java .util .concurrent .ExecutionException ;
9798import java .util .concurrent .Future ;
@@ -384,8 +385,7 @@ enum TimingKind {
384385 }
385386
386387 /** accumulated time in ns of a given {@link TimingKind#name}; {@link String} key for pretty XStream form */
387- @ GuardedBy ("this" )
388- @ CheckForNull Map <String , Long > timings ;
388+ @ NonNull Map <String , Long > timings = new ConcurrentHashMap <>();
389389
390390 @ Deprecated
391391 public CpsFlowExecution (String script , FlowExecutionOwner owner ) throws IOException {
@@ -413,6 +413,10 @@ public CpsFlowExecution(String script, boolean sandbox, FlowExecutionOwner owner
413413 private Object readResolve () {
414414 if (loadedScripts ==null )
415415 loadedScripts = new HashMap <>(); // field added later
416+ // Convert timings to concurrent hash map
417+ if (!(timings instanceof ConcurrentHashMap )) {
418+ timings = timings == null ? new ConcurrentHashMap <>() : new ConcurrentHashMap <>(timings );
419+ }
416420 return this ;
417421 }
418422
@@ -424,16 +428,7 @@ private Timing(TimingKind kind) {
424428 start = System .nanoTime ();
425429 }
426430 @ Override public void close () {
427- synchronized (CpsFlowExecution .this ) {
428- if (timings == null ) {
429- timings = new HashMap <>();
430- }
431- Long orig = timings .get (kind .name ());
432- if (orig == null ) {
433- orig = 0L ;
434- }
435- timings .put (kind .name (), orig + System .nanoTime () - start );
436- }
431+ timings .merge (kind .name (), System .nanoTime () - start , Long ::sum );
437432 }
438433 }
439434
@@ -448,12 +443,10 @@ Timing time(TimingKind kind) {
448443
449444 static final Logger TIMING_LOGGER = Logger .getLogger (CpsFlowExecution .class .getName () + ".timing" );
450445
451- synchronized void logTimings () {
452- if (timings != null && TIMING_LOGGER .isLoggable (Level .FINE )) {
446+ void logTimings () {
447+ if (TIMING_LOGGER .isLoggable (Level .FINE )) {
453448 Map <String , String > formatted = new TreeMap <>();
454- for (Map .Entry <String , Long > entry : timings .entrySet ()) {
455- formatted .put (entry .getKey (), entry .getValue () / 1000 / 1000 + "ms" );
456- }
449+ timings .forEach ((k , v ) -> formatted .put (k , v / 1000 / 1000 + "ms" ));
457450 TIMING_LOGGER .log (Level .FINE , "timings for {0}: {1}" , new Object [] {owner , formatted });
458451 }
459452 }
@@ -1643,11 +1636,7 @@ public void marshal(Object source, HierarchicalStreamWriter w, MarshallingContex
16431636 if (e .durabilityHint != null ) {
16441637 writeChild (w , context , "durabilityHint" , e .durabilityHint , FlowDurabilityHint .class );
16451638 }
1646- synchronized (e ) {
1647- if (e .timings != null ) {
1648- writeChild (w , context , "timings" , e .timings , Map .class );
1649- }
1650- }
1639+ writeChild (w , context , "timings" , e .timings , Map .class );
16511640 writeChild (w , context , "sandbox" , e .sandbox , Boolean .class );
16521641 if (e .user != null ) {
16531642 writeChild (w , context , "user" , e .user , String .class );
@@ -1931,14 +1920,10 @@ public void autopersist(@NonNull FlowNode n) throws IOException {
19311920 continue ;
19321921 }
19331922 if (exec instanceof CpsFlowExecution ) {
1934- Map <String , Long > timings = ((CpsFlowExecution ) exec ).timings ;
1935- if (timings != null ) {
1936- pw .println ("Timings for " + run + ":" );
1937- for (Map .Entry <String , Long > entry : new TreeMap <>(timings ).entrySet ()) {
1938- pw .println (" " + entry .getKey () + "\t " + entry .getValue () / 1000 / 1000 + "ms" );
1939- }
1940- pw .println ();
1941- }
1923+ Map <String , Long > sortedTimings = new TreeMap <>(((CpsFlowExecution ) exec ).timings );
1924+ pw .println ("Timings for " + run + ":" );
1925+ sortedTimings .forEach ((k , v ) -> pw .println (" " + k + "\t " + v / 1000 / 1000 + "ms" ));
1926+ pw .println ();
19421927 }
19431928 }
19441929 }
0 commit comments