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.