1 Overview

Bordeaux‑Threads is a lightweight, open‑source Java concurrency library designed to provide efficient and flexible thread management for high‑performance applications. Named after the French wine region known for its balanced and refined character, Bordeaux‑Threads emphasizes simplicity, low overhead, and predictable execution. It offers configurable thread pools, work‑stealing algorithms, and synchronization primitives that integrate seamlessly with Java’s standard executor framework. The library is maintained by a small community of developers and is often used in server‑side systems, real‑time data processing, and game engines where precise thread control is required.

1.1 History and Naming

Bordeaux‑Threads was first released in 2017 by a group of independent Java developers seeking a lightweight alternative to the built‑in concurrency utilities. The name was chosen to evoke the balance and refinement associated with Bordeaux wines, reflecting the library’s goal of balancing performance and simplicity. The project grew through contributions from a small open‑source community, with regular releases adding new features and optimizations.

1.2 Design Philosophy

The design philosophy of Bordeaux‑Threads centers on three principles: minimal overhead, predictable behavior, and ease of integration. The library avoids heavy abstractions and instead provides direct control over thread pool behavior, task scheduling, and synchronization. It aims to complement rather than replace Java’s standard concurrency framework, allowing developers to drop in specific components where needed.

2 Core Architecture

2.1 Thread Pool Models

Bordeaux‑Threads provides three fundamental thread pool models, each optimized for different workload patterns.

2.1.1 Fixed‑Size Pools

Fixed‑size pools maintain a constant number of worker threads. Tasks are submitted to a queue and executed by the available threads. This model is suitable for workloads with a known, consistent level of parallelism and is the default pool type.

2.1.2 Cached Pools

Cached pools dynamically create new threads as tasks arrive and reuse idle threads. Threads that remain idle for a configurable timeout are terminated. This model is useful for bursty workloads where the number of concurrent tasks varies significantly.

2.1.3 Work‑Stealing Pools

Work‑stealing pools divide tasks into smaller subtasks and allow idle threads to “steal” work from busy threads. This approach maximizes CPU utilization for fork‑join‑style parallel computations. Bordeaux‑Threads implements a custom work‑stealing algorithm that reduces contention compared to Java’s built‑in ForkJoinPool.

2.2 Scheduler and Queuing

The scheduler in Bordeaux‑Threads manages task distribution across worker threads, using flexible queuing strategies.

2.2.1 Priority Queues

Priority queues allow tasks to be ordered by a user‑defined priority value. Higher‑priority tasks are executed before lower‑priority ones. This feature is useful in real‑time systems where some tasks must meet strict deadlines.

2.2.2 Bounded Queues

Bounded queues impose a maximum capacity on the task queue. When the queue is full, the submitter can either block, reject the task, or execute it on the calling thread, depending on the configured policy. This prevents memory exhaustion under high load.

2.3 Task Submission and Execution

2.3.1 Callable and Runnable Support

Bordeaux‑Threads supports both Runnable and Callable tasks. Runnable tasks return no result, while Callable tasks return a value and can throw checked exceptions. The submission methods follow the same signatures as Java’s ExecutorService.

2.3.2 Future and CompletableFuture Integration

Submitted tasks return a Future or CompletableFuture (depending on the submission method), enabling asynchronous result retrieval and composition. Bordeaux‑Threads extends the standard CompletableFuture with custom executors, allowing chaining and combining of tasks within the same pool.

3 Feature Set

3.1 Configurable Lifecycle Hooks

Lifecycle hooks allow developers to attach custom logic before or after task execution, and to define how exceptions are handled.

3.1.1 Pre‑Run and Post‑Run Handlers

Pre‑run handlers execute on the worker thread just before a task starts. Post‑run handlers execute immediately after the task completes (whether normally or exceptionally). Common uses include logging, setting thread‑local variables, and resource cleanup.

3.1.2 Exception Handling Policies

Developers can specify policies for uncaught exceptions: log and continue, retry the failed task, or propagate the exception to the thread group. This flexibility helps prevent silent failures while maintaining system stability.

3.2 Metrics and Monitoring

3.2.1 Thread Count, Queue Depth, and Latency

The library exposes real‑time metrics such as active thread count, pending task count (queue depth), and average task latency. These metrics can be polled programmatically or via adapters.

3.2.2 Integration with JMX and Micrometer

Bordeaux‑Threads provides built‑in adapters for Java Management Extensions (JMX) and the Micrometer metrics library. Administrators can monitor pool health through standard monitoring tools and dashboards.

3.3 Synchronization Utilities

The library includes lightweight synchronization primitives optimized for high‑contention scenarios.

3.3.1 Optimized ReentrantLocks

Bordeaux‑Threads offers an optimized reentrant lock that reduces memory barriers and uses a more compact internal structure than Java’s ReentrantLock, resulting in lower overhead for short critical sections.

3.3.2 Read‑Write Locks with Backoff

The read‑write lock implementation includes exponential backoff for writers attempting to acquire the lock under heavy read contention. This reduces livelock and improves overall throughput in read‑dominated workloads.

4 Usage Guide

4.1 Installation and Dependencies

Bordeaux‑Threads is distributed as a single JAR file available from Maven Central. The library has no mandatory runtime dependencies beyond Java 8 or later. Optional dependencies (e.g., Micrometer) are not required for basic operation.

4.2 Basic Configuration Example

4.2.1 Creating a Default Thread Pool

import com.bordeaux.threads.ThreadPool;

ThreadPool pool = ThreadPool.newFixedPool(4); // 4 worker threads
pool.submit(() -> System.out.println("Hello from Bordeaux‑Threads"));

4.2.2 Tuning Pool Size and Queue Capacity

ThreadPool pool = ThreadPool.newBuilder()
    .poolType(PoolType.FIXED)
    .corePoolSize(8)
    .maxPoolSize(16)  // for cached pools
    .queueCapacity(1000)
    .build();

4.3 Advanced Patterns

4.3.1 Thread‑Local Work Interleaving

For tasks that must share state scoped to a thread, Bordeaux‑Threads provides a mechanism to preserve and restore thread‑local variables across task boundaries. This is done by configuring a ThreadLocalSupplier and enabling the “thread interleaving” mode in the pool builder.

4.3.2 Cooperative Cancellation

Tasks can be marked as cancellable by implementing the Cancellable interface. The pool then periodically checks a cancellation flag and interrupts blocked tasks. This pattern is useful for long‑running tasks that must respond to shutdown or user requests.

5 Performance and Benchmarks

5.1 Throughput and Latency Comparisons

5.1.1 Versus Java’s ForkJoinPool

In microbenchmarks using synthetic fork‑join workloads, Bordeaux‑Threads’ work‑stealing pool achieves up to 15% higher throughput than ForkJoinPool under moderate contention, due to its reduced lock contention. Under very high contention, both perform similarly.

5.1.2 Versus Executors.newWorkStealingPool

Bordeaux‑Threads demonstrates lower latency for short tasks (under 1 ms) compared to the JDK’s work‑stealing pool, as it avoids certain internal overheads associated with the default implementation. For longer tasks, the differences are negligible.

5.2 Memory Footprint and Overhead

The library’s per‑thread overhead is approximately 2 KB lower than Java’s standard thread pool, due to compact internal data structures. The total memory footprint for a pool of 8 threads is roughly 30–40 KB less than an equivalent ThreadPoolExecutor with the same configuration.

6 Community and Licensing

6.1 Maintainers and Contributors

Bordeaux‑Threads is maintained by a core team of three developers, with contributions from approximately 30 community members. The project uses GitHub for issue tracking and pull requests, and maintains an active discussion forum.

6.2 License (Apache 2.0)

The library is released under the Apache License, Version 2.0. This permissive license allows use, modification, and distribution in both open‑source and proprietary projects.

Several community‑developed extensions exist, including a Spring Boot starter for automatic ThreadPool bean creation, an adapter for Quasar fibers, and a bridge to Project Loom virtual threads (experimental). The core library itself remains minimal, with extensions maintained separately.