MCPcopy Create free account
hub / github.com/apache/groovy / Agent

Class Agent

src/main/java/groovy/concurrent/Agent.java:77–508  ·  view source on GitHub ↗

A thread-safe mutable-value container inspired by Clojure's agents and GPars' Agent. An Agent wraps a value that can be read by any thread but modified only through serialized update functions. Updates are queued and applied one at a time on a dedicated executor, guaranteeing tha

Source from the content-addressed store, hash-verified

75 * @since 6.0.0
76 */
77public final class Agent<T> {
78
79 /** Default per-subscriber buffer size for {@link #changes()}. */
80 private static final int DEFAULT_CHANGES_BUFFER = 256;
81
82 private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
83 private final ExecutorService updateExecutor;
84 private final Object lifecycleLock = new Object();
85 private volatile T value;
86 private volatile SubmissionPublisher<T> changesPublisher;
87 private volatile boolean shutdownInvoked;
88
89 private Agent(T initialValue, ExecutorService executor) {
90 this.value = initialValue;
91 this.updateExecutor = executor;
92 }
93
94 /**
95 * Creates an agent with the given initial value, using a
96 * single-thread executor for serialized updates.
97 *
98 * @param initialValue the starting value
99 * @param <T> the value type
100 * @return a new agent
101 */
102 public static <T> Agent<T> create(T initialValue) {
103 return new Agent<>(initialValue,
104 Executors.newSingleThreadExecutor(r -> {
105 Thread t = new Thread(r, "groovy-agent");
106 t.setDaemon(true);
107 return t;
108 }));
109 }
110
111 /**
112 * Creates an agent backed by the given pool for update execution.
113 * Updates are still serialized (only one at a time), but they run
114 * on the pool's threads.
115 *
116 * @param initialValue the starting value
117 * @param pool the pool to use for updates
118 * @param <T> the value type
119 * @return a new agent
120 */
121 public static <T> Agent<T> create(T initialValue, Pool pool) {
122 Objects.requireNonNull(pool, "pool must not be null");
123 // Use a SerialExecutor to serialize updates on the pool's threads.
124 // We cannot use newSingleThreadExecutor with a delegating ThreadFactory
125 // because that breaks the executor's internal task loop.
126 return new Agent<>(initialValue, new SerialExecutor(pool));
127 }
128
129 /**
130 * Returns the current value. This is a non-blocking snapshot read.
131 *
132 * @return the current value
133 */
134 public T get() {

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected