/*
 * Copyright 2002-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.core.metrics.jfr;

import java.util.ArrayDeque;
import java.util.Deque;

import org.springframework.core.metrics.ApplicationStartup;
import org.springframework.core.metrics.StartupStep;

/**
 * {@link ApplicationStartup} implementation for the Java Flight Recorder.
 * <p>This variant records {@link StartupStep} as Flight Recorder events. Because
 * such events only support base types, the
 * {@link org.springframework.core.metrics.StartupStep.Tags} are serialized as a
 * single String attribute.
 * <p>Once this is configured on the application context, you can record data by
 * launching the application with recording enabled:
 * {@code java -XX:StartFlightRecording:filename=recording.jfr,duration=10s -jar app.jar}.
 *
 * @author Brian Clozel
 * @since 5.3
 */
public class FlightRecorderApplicationStartup implements ApplicationStartup {

	private long currentSequenceId;

	private final Deque<Long> currentSteps;


	public FlightRecorderApplicationStartup() {
		this.currentSequenceId = 0;
		this.currentSteps = new ArrayDeque<>();
		this.currentSteps.offerFirst(0L);
	}


	@Override
	public StartupStep start(String name) {
		FlightRecorderStartupStep step = new FlightRecorderStartupStep(++this.currentSequenceId, name,
				this.currentSteps.getFirst(), committedStep -> this.currentSteps.removeFirst());
		this.currentSteps.offerFirst(this.currentSequenceId);
		return step;
	}

}

@@ -17,17 +17,17 @@
 2002-202
-0
+1
  the ori
@@ -680,21 +680,16 @@
 va.util.
-Array
 Deque;%0Ai
@@ -704,21 +704,95 @@
 va.util.
-Deque
+concurrent.ConcurrentLinkedDeque;%0Aimport java.util.concurrent.atomic.AtomicLong
 ;%0A%0Aimpor
@@ -1572,17 +1572,29 @@
 private 
-l
+final AtomicL
 ong curr
@@ -1606,16 +1606,36 @@
 quenceId
+ = new AtomicLong(0)
 ;%0A%0A%09priv
@@ -1736,54 +1736,35 @@
 entS
-equenceId = 0;%0A%09%09this.currentSteps = new Array
+teps = new ConcurrentLinked
 Dequ
@@ -1805,10 +1805,36 @@
 rst(
-0L
+this.currentSequenceId.get()
 );%0A%09
@@ -1895,40 +1895,120 @@
 %7B%0A%09%09
-FlightRecorderStartupStep step =
+long sequenceId = this.currentSequenceId.incrementAndGet();%0A%09%09this.currentSteps.offerFirst(sequenceId);%0A%09%09return
  new
@@ -2038,23 +2038,9 @@
 tep(
-++this.currentS
+s
 eque
@@ -2136,82 +2136,31 @@
 irst
-());%0A%09%09this.currentSteps.offerFirst(this.currentSequenceId);%0A%09%09return step
+Occurrence(sequenceId))
 ;%0A%09%7D

Make FlightRecorderApplicationStartup thread safe