What is Non-Blocking ?

Suryansh Shrivastava
2 min readSep 2, 2023

--

In computing, a non-blocking algorithm or operation allows other threads or operations to proceed if the current one can’t be executed immediately. This is in contrast to blocking operations, where the current operation holds up other activities until it completes. Non-blocking approaches are used to maximize system performance and responsiveness.

Non-Blocking in Spring WebFlux

Spring WebFlux is built on top of Project Reactor, which is designed to be non-blocking from the ground up. The framework uses asynchronous I/O for handling requests and responses, enabling a single thread to manage multiple connections simultaneously.

Here’s a simplified example using Spring WebFlux to demonstrate its non-blocking nature:

@RestController
public class NonBlockingController {

@GetMapping("/non-blocking")
public Mono<String> get() {
return Mono.just("Hello, World!")
.delayElement(Duration.ofSeconds(2)); // Simulates a delay
}
}

In this example, when a request hits the `/non-blocking` endpoint, the delay doesn’t block the thread. Instead, the thread is free to handle other requests while waiting for the delay to complete. The `Mono` type represents a single value that will be emitted in the future in a non-blocking manner.

Non-Blocking in Go

Go’s concurrency model, featuring goroutines and channels, allows for efficient non-blocking I/O operations. When a goroutine performs an I/O operation, it doesn’t block the entire thread; instead, it yields the processor, allowing other goroutines to run.

Here’s a simple Go example demonstrating its non-blocking behavior:

go
package main
import (
"fmt"
"time"
)
func worker(ch chan int) {
for i := 0; i < 5; i++ {
time.Sleep(time.Second)
ch <- i
}
close(ch)
}
func main() {
ch := make(chan int)
go worker(ch)
for {
select {
case i, ok := <-ch:
if !ok {
return
}
fmt.Println("Received:", i)
default:
fmt.Println("Doing something else…")
time.Sleep(200 * time.Millisecond)
}
}
}

In this Go program, the worker goroutine sleeps for 1 second between each iteration and then sends an integer through the channel. Meanwhile, the main function has a loop where it attempts to read from the channel. If no data is available (default case in the select statement), it does something else without blocking, waiting for the data to be sent to the channel.

To learn more about Go’s select statement refer the following article

Summary

Both Spring WebFlux and Go are designed to be non-blocking:

- Spring WebFlux leverages the Project Reactor library and the underlying asynchronous I/O capabilities of the Java ecosystem to build non-blocking web applications.
- Go uses its goroutine-based concurrency model to ensure that I/O operations are non-blocking by design, allowing for efficient multitasking.

These non-blocking capabilities make both technologies highly scalable and efficient, especially for handling high-concurrency scenarios.

--

--

Suryansh Shrivastava

Protocol Engineer & Blockchain Developer | Go | Solidity | Move | Cross-Chain & Interop | Smart Contracts | Defi (AMM, Lending, Derivatives and Stable-coins)