Java
Java provides built-in support for concurrency through the java.util.concurrent
package. It offers various concurrency primitives and utilities, such as threads, locks, synchronization, and thread-safe collections.
Here’s an example of creating and starting a thread in Java:
public class MyThread extends Thread {
@Override
public void run() {
// Thread logic goes here
}
}
// Starting the thread
MyThread thread = new MyThread();
thread.start();
Java also supports higher-level abstractions like the ExecutorService
for managing thread pools and the CompletableFuture
for asynchronous programming.
Python
Python supports concurrency through multiple approaches, including threads, multiprocessing, and asynchronous programming using the asyncio
module.
Here’s an example of creating and starting a thread in Python:
import threading
def worker():
# Thread logic goes here
pass
# Starting the thread
thread = threading.Thread(target=worker)
thread.start()
Python’s multiprocessing
module allows for true parallelism by spawning multiple processes, while the asyncio
module provides a framework for writing asynchronous code using coroutines and event loops.
JavaScript
JavaScript, being a single-threaded language, handles concurrency through an event-driven, non-blocking I/O model. It utilizes callbacks, promises, and async/await to manage asynchronous operations.
Here’s an example of using promises in JavaScript:
function fetchData() {
return new Promise((resolve, reject) => {
// Asynchronous operation
// ...
resolve(data);
});
}
fetchData()
.then(data => {
// Handle the resolved data
})
.catch(error => {
// Handle any errors
});
JavaScript’s event loop manages the execution of asynchronous tasks, allowing for non-blocking I/O and concurrency without the need for explicit threads.
Go
Go (Golang) has concurrency as a first-class citizen in the language. It provides goroutines, which are lightweight threads managed by the Go runtime, and channels for communication and synchronization between goroutines.
Here’s an example of creating and starting a goroutine in Go:
func worker(id int) {
// Goroutine logic goes here
}
// Starting the goroutine
go worker(1)
Go’s concurrency primitives, such as goroutines and channels, make it easy to write concurrent and parallel programs. The language’s runtime automatically handles scheduling and management of goroutines.
Rust
Rust takes a unique approach to concurrency by enforcing thread safety at compile-time through its ownership system and borrow checker. It provides safe and efficient concurrency primitives, such as threads, mutexes, and channels.
Here’s an example of creating and starting a thread in Rust:
use std::thread;
fn main() {
let handle = thread::spawn(|| {
// Thread logic goes here
});
handle.join().unwrap();
}
Rust’s ownership system ensures that data is owned by only one thread at a time, preventing data races and other concurrency bugs at compile-time.