Install
$ agentstack add skill-ngxtm-devkit-java-concurrency ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ● Shell / process execution Used
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Java Concurrency Standards
Executor Framework
// Fixed thread pool - bounded, predictable
ExecutorService executor = Executors.newFixedThreadPool(
Runtime.getRuntime().availableProcessors()
);
// Cached thread pool - unbounded, use carefully
ExecutorService cached = Executors.newCachedThreadPool();
// Scheduled executor
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
scheduler.scheduleAtFixedRate(task, 0, 1, TimeUnit.SECONDS);
// Virtual threads (Java 21+)
ExecutorService virtual = Executors.newVirtualThreadPerTaskExecutor();
// Custom thread pool
ThreadPoolExecutor custom = new ThreadPoolExecutor(
4, // core pool size
8, // max pool size
60, TimeUnit.SECONDS, // keep alive
new LinkedBlockingQueue<>(100), // work queue
new ThreadPoolExecutor.CallerRunsPolicy() // rejection handler
);
// Always shutdown executors
try {
executor.shutdown();
if (!executor.awaitTermination(30, TimeUnit.SECONDS)) {
executor.shutdownNow();
}
} catch (InterruptedException e) {
executor.shutdownNow();
Thread.currentThread().interrupt();
}
CompletableFuture
// Async execution
CompletableFuture userFuture = CompletableFuture
.supplyAsync(() -> userService.findById(id), executor);
// Chaining
CompletableFuture result = userFuture
.thenApply(User::getEmail)
.thenApply(String::toLowerCase)
.exceptionally(ex -> "unknown@example.com");
// Combine multiple futures
CompletableFuture profile = CompletableFuture
.allOf(userFuture, ordersFuture, preferencesFuture)
.thenApply(v -> new UserProfile(
userFuture.join(),
ordersFuture.join(),
preferencesFuture.join()
));
// Either/race
CompletableFuture fastest = CompletableFuture
.anyOf(primaryService, fallbackService)
.thenApply(result -> (String) result);
// Timeout (Java 9+)
CompletableFuture withTimeout = userFuture
.orTimeout(5, TimeUnit.SECONDS)
.exceptionally(ex -> defaultUser);
Synchronization
// synchronized block - prefer over method
private final Object lock = new Object();
public void update(String value) {
synchronized (lock) {
// critical section
}
}
// ReentrantLock - more flexible
private final ReentrantLock lock = new ReentrantLock();
public void process() {
lock.lock();
try {
// critical section
} finally {
lock.unlock();
}
}
// ReadWriteLock - multiple readers, single writer
private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
public String read() {
rwLock.readLock().lock();
try {
return data;
} finally {
rwLock.readLock().unlock();
}
}
public void write(String value) {
rwLock.writeLock().lock();
try {
data = value;
} finally {
rwLock.writeLock().unlock();
}
}
Atomic Classes
// Atomic primitives
AtomicInteger counter = new AtomicInteger(0);
counter.incrementAndGet();
counter.compareAndSet(expected, newValue);
// Atomic reference
AtomicReference configRef = new AtomicReference<>(initialConfig);
configRef.updateAndGet(config -> config.withNewValue(value));
// LongAdder for high contention
LongAdder adder = new LongAdder();
adder.increment();
long sum = adder.sum();
Virtual Threads (Java 21+)
// Simple virtual thread
Thread.startVirtualThread(() -> {
// blocking I/O is fine
String data = httpClient.get(url);
process(data);
});
// With executor
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
List> futures = tasks.stream()
.map(task -> executor.submit(task::execute))
.toList();
for (Future future : futures) {
results.add(future.get());
}
}
// Don't use with CPU-bound tasks
// Don't use synchronized for long operations (use ReentrantLock)
Best Practices
- Prefer high-level constructs (Executor, CompletableFuture) over raw threads
- Size thread pools based on task type (CPU-bound: cores, I/O-bound: higher)
- Always handle InterruptedException - restore interrupt status
- Use virtual threads for I/O-bound tasks (Java 21+)
- Prefer Atomic classes over synchronized for simple counters
- Immutability is the best synchronization
References
- [Executor Patterns](references/executor-patterns.md) - Thread pool configuration, shutdown
- [CompletableFuture](references/completable-future.md) - Async composition patterns
- [Virtual Threads](references/virtual-threads.md) - Java 21+ patterns
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: ngxtm
- Source: ngxtm/devkit
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.