Last active
August 26, 2025 11:25
-
-
Save iuridiniz/94ee78d844989bbeb1ce1d7a81e26e59 to your computer and use it in GitHub Desktop.
sync.Once (golang) in java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public class OnceExample { | |
| public static void main(String[] args) { | |
| testSimpleOnce(); | |
| testStatefulOnce(); | |
| } | |
| private static void testSimpleOnce() { | |
| SimpleOnce simpleOnce = new SimpleOnce(); | |
| System.out.println("Initial state: " + simpleOnce.getState()); // NOT_EXECUTED | |
| try { | |
| simpleOnce.doOnce(() -> System.out.println("Executed once!")); | |
| System.out.println("After execution: " + simpleOnce.getState()); // COMPLETED | |
| } catch (Exception e) { | |
| e.printStackTrace(); | |
| } | |
| } | |
| private static void testStatefulOnce() { | |
| StatefulOnce statefulOnce = new StatefulOnce(); | |
| System.out.println("Initial state: " + statefulOnce.getState()); // NOT_STARTED | |
| // Simulate concurrent execution | |
| Thread t1 = new Thread(() -> { | |
| try { | |
| statefulOnce.doOnce(() -> { | |
| System.out.println("State during execution: " + statefulOnce.getState()); // RUNNING | |
| try { Thread.sleep(1000); } catch (InterruptedException e) {} | |
| System.out.println("Execution completed!"); | |
| }); | |
| } catch (Exception e) { | |
| e.printStackTrace(); | |
| } | |
| }); | |
| t1.start(); | |
| // Check state while running | |
| try { | |
| Thread.sleep(100); | |
| System.out.println("State while running: " + statefulOnce.getState()); // RUNNING | |
| t1.join(); | |
| System.out.println("Final state: " + statefulOnce.getState()); // COMPLETED | |
| } catch (InterruptedException e) { | |
| e.printStackTrace(); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import java.util.concurrent.atomic.AtomicBoolean; | |
| public class SimpleOnce { | |
| public enum State { NOT_EXECUTED, COMPLETED } | |
| private final AtomicBoolean done = new AtomicBoolean(false); | |
| public void doOnce(Runnable action) throws Exception { | |
| if (done.get()) { | |
| return; | |
| } | |
| synchronized (this) { | |
| if (done.get()) { | |
| return; | |
| } | |
| try { | |
| action.run(); | |
| done.set(true); | |
| } catch (Exception e) { | |
| throw e; | |
| } | |
| } | |
| } | |
| public State getState() { | |
| return done.get() ? State.COMPLETED : State.NOT_EXECUTED; | |
| } | |
| public boolean isCompleted() { | |
| return done.get(); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import java.util.concurrent.atomic.AtomicReference; | |
| public class StatefulOnce { | |
| public enum State { NOT_STARTED, RUNNING, COMPLETED } | |
| private final AtomicReference<State> state = new AtomicReference<>(State.NOT_STARTED); | |
| private final Object lock = new Object(); | |
| public void doOnce(Runnable action) throws Exception { | |
| if (state.get() == State.COMPLETED) { | |
| return; | |
| } | |
| synchronized (lock) { | |
| if (state.get() == State.COMPLETED) { | |
| return; | |
| } | |
| if (state.get() == State.NOT_STARTED) { | |
| state.set(State.RUNNING); | |
| try { | |
| action.run(); | |
| state.set(State.COMPLETED); | |
| } catch (Exception e) { | |
| state.set(State.NOT_STARTED); | |
| throw e; | |
| } | |
| } | |
| } | |
| } | |
| public State getState() { | |
| return state.get(); | |
| } | |
| public boolean isCompleted() { | |
| return state.get() == State.COMPLETED; | |
| } | |
| public boolean isRunning() { | |
| return state.get() == State.RUNNING; | |
| } | |
| public boolean isNotStarted() { | |
| return state.get() == State.NOT_STARTED; | |
| } | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Key Differences
Both implementations are exception-safe and allow retries after failures, but
StatefulOnceprovides better visibility into the execution state for concurrent scenarios.