Threads
The following table lists approximate mapping of threading types and methods in Java to Rust:
Java | Rust |
---|---|
Thread | std::thread::Thread |
Thread.start | std::thread::spawn |
Thread.join | std::thread::JoinHandle |
Thread.sleep | std::thread::sleep |
synchronized | - |
ReentrantLock | std::sync::Mutex |
ReentrantReadWriteLock | std::sync::RwLock |
Semaphore | - |
Condition | std::sync::Condvar |
java.util.concurrent.atomic.* | std::sync::atomic |
volatile | - |
ThreadLocal | std::thread_local |
Launching a thread and waiting for it to finish works the same way in Java and Rust. Below is a simple Java program that creates a thread and then waits for it to end:
Thread thread = new Thread(() -> {
System.out.println("Hello from a thread!"); });
thread.start();
thread.join(); // wait for thread to finish
The same code in Rust looks as follows:
use std::thread;
fn main() {
let thread = thread::spawn(|| println!("Hello from a thread!"));
thread.join().unwrap(); // wait for thread to finish
}
Creating and initializing a thread object and starting a thread are two
different actions in Java whereas in Rust both happen at the same time with
thread::spawn
.
Java 21 introduced the Thread.Builder API for creating and starting both platform and virtual threads. Platform threads are the traditional threads in Java that are thin wrappers around OS threads - the thread that we created above is an example of a platform thread. Virtual threads on the other hand are lightweight threads that are not directly tied to OS threads.
Here's how we can use the thread builder API to create a platform thread in Java:
Thread platformThread = Thread.ofPlatform().unstarted(() -> {
System.out.println("Hello from a platform thread!"); });
platformThread.start();
platformThread.join();
And here's how we can create a virtual thread:
Thread virtualThread = Thread.ofVirtual().unstarted(() -> {
System.out.println("Hello from a virtual thread!"); });
virtualThread.start();
virtualThread.join();
Note: Rust does not have support for virtual threads.
Working with thread pools
In Java, we can create a thread pool using the Executor framework.
Consider the following Java example:
static void concurrentProcessing() throws ExecutionException, InterruptedException {
// Using Callable so a value can be returned after processing by a thread
Callable<Integer> sportsNews = () -> {
for (int i = 0; i < 10; i++) {
Thread.sleep(1000); // sleep for 1 second
System.out.println("Manchester United is winning " + i);
}
// Just return some random number to illustrate return
return 42;
};
Callable<Integer> leaguePoints = () -> {
for (int i = 0; i < 10; i++) {
Thread.sleep(700); // sleep for 700 milliseconds
int points = 40 + i;
System.out.println("Manchester has " + points + " league points");
}
// Just return some random number
return 24;
};
// A placeholder for Future objects
List<Future<Integer>> futures = new ArrayList<>();
// A temporary storage for results returned by threads
List<Integer> results = new ArrayList<>();
try (
final ExecutorService service = Executors.newFixedThreadPool(2); // Create a pool of 2 threads
) {
futures.add(service.submit(sportsNews));
futures.add(service.submit(leaguePoints));
for (var future : futures) {
results.add(future.get());
}
}
for (Integer result : results) {
System.out.println("Got the result: " + result);
}
}
public static void main(String[] args) {
try {
concurrentProcessing();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
Here's the output of running the Java code above:
Manchester has 40 league points
Manchester United is winning 0
Manchester has 41 league points
Manchester United is winning 1
Manchester has 42 league points
Manchester has 43 league points
Manchester United is winning 2
Manchester has 44 league points
Manchester United is winning 3
Manchester has 45 league points
Manchester has 46 league points
Manchester United is winning 4
Manchester has 47 league points
Manchester United is winning 5
Manchester has 48 league points
Manchester United is winning 6
Manchester has 49 league points
Manchester United is winning 7
Manchester United is winning 8
Manchester United is winning 9
Got the result: 42
Got the result: 24
Note: Your output might look slighly different.
Here's the Rust version of the code. We are using the Rayon library to create a thread pool.
use std::{thread, time};
use std::sync::Mutex;
fn sports_news() -> i32 {
for i in 0..10 {
let seconds = time::Duration::from_millis(1000);
thread::sleep(seconds); // sleep for 1 second
println!("Manchester United is winning {}", i);
}
// Just return some number to illustrate return
return 42;
}
fn league_points() -> i32 {
for i in 0..10 {
let seconds = time::Duration::from_millis(700);
thread::sleep(seconds); // sleep for 700 milliseconds
let points = 40 + i;
println!("Manchester has {} league points", points);
}
// Just return some number
return 24;
}
fn concurrent_processing() {
// A temporary storage for results returned by threads
let result_vec = Mutex::new(Vec::new());
let pool = rayon::ThreadPoolBuilder::new()
.num_threads(2) // Create a pool of 2 threads
.build()
.unwrap();
pool.install(|| {
rayon::scope(|s| {
let result_vec = &result_vec;
// spawn thread to process sports news
s.spawn(move |_| {
let result1 = sports_news();
result_vec.lock().unwrap().push(result1);
});
// spawn thread to process league points
s.spawn(move |_| {
let result2 = league_points();
result_vec.lock().unwrap().push(result2);
});
});
});
for result in result_vec.lock().unwrap().iter() {
println!("Got the result: {:?}", result);
}
}
fn main() {
concurrent_processing();
}
Here's the output of the Rust code above:
Manchester has 40 league points
Manchester United is winning 0
Manchester has 41 league points
Manchester United is winning 1
Manchester has 42 league points
Manchester has 43 league points
Manchester United is winning 2
Manchester has 44 league points
Manchester United is winning 3
Manchester has 45 league points
Manchester has 46 league points
Manchester United is winning 4
Manchester has 47 league points
Manchester United is winning 5
Manchester has 48 league points
Manchester United is winning 6
Manchester has 49 league points
Manchester United is winning 7
Manchester United is winning 8
Manchester United is winning 9
Got the result: 24
Got the result: 42