In reactive programming, a data flow is like a pipeline where data travels through a series of transformations and reactions — all done in a declarative, non-blocking, and asynchronous way.
You don’t “call” data; it comes to you. You set up a pipeline and let data flow through it.
Reactive Programming is a programming paradigm focused on asynchronous data streams and the propagation of change. It’s all about reacting to data as it comes in — like events, user interactions, or data updates — and building systems that respond to these changes automatically and efficiently.
Posted inБез рубрики|Comments Off on Java.Multithreading.Write a thread-safe implementation of a class with a non-blocking BigInteger next() method that returns the elements of the sequence: [1, 2, 4, 8, 16, …].
💪 Writing a non-blocking ArrayList is a tricky but fun task — because arrays require index-based coordination, which is much harder to do without locks than a linked structure like a stack.
But let’s take it step by step and aim for a minimal lock-free-ish dynamic array structure — using atomic operations only.
Is thread-safe, but not lock-free (uses internal synchronization)
import java.util.Deque;
import java.util.LinkedList;
import java.util.concurrent.Semaphore;
public class SemaphoreStack<T> {
private final Deque<T> stack = new LinkedList<>();
private final Semaphore items = new Semaphore(0); // Tracks how many items are available
private final Object lock = new Object(); // Guards access to the stack
public void push(T value) {
synchronized (lock) {
stack.push(value);
}
items.release(); // Signal: one more item available
}
public T pop() throws InterruptedException {
items.acquire(); // Wait until item is available
synchronized (lock) {
return stack.pop();
}
}
}
🧪 Example Usage:
public class Main {
public static void main(String[] args) throws InterruptedException {
SemaphoreStack<Integer> stack = new SemaphoreStack<>();
stack.push(1);
stack.push(2);
System.out.println(stack.pop()); // 2
System.out.println(stack.pop()); // 1
}
}
🔍 How It Works:
items.acquire() blocks if the stack is empty
items.release() increases the count (available items)
synchronized protects the internal stack from race conditions
🔄 Controlling the execution order of threads (T1 → T2 → T3) is a classic multithreading problem, and there are several ways to achieve it — depending on your style and needs.