Introduction to threads programming

Threads in Java

private static void hello() {
    var t1 = new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("Hello from thread 1");
        }
    });
    var t2 = new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("Hello from thread 2");
        }
    });
    t1.start();
    t2.start();
}

Using Lambdas

private static void hello() {
    var t1 = new Thread(() -> System.out.println("Hello from thread 1"));
    var t2 = new Thread(() -> System.out.println("Hello from thread 2"));
    t1.start();
    t2.start();
}

Try it

public static void main(String[] args) {
	hello();
	System.out.println("Good Bye");
}

Output

Good Bye
Hello from thread 2
Hello from thread 1

Need to wait for execution to end

private static void hello() throws InterruptedException {
    var t1 = new Thread(() -> System.out.println("Hello from thread 1"));
    var t2 = new Thread(() -> System.out.println("Hello from thread 2"));
    t1.start();
    t2.start();
    t1.join;
    t2.join;
}

Output:

Hello from thread 2
Hello from thread 1
Good Bye

Look at throws InterruptedException

Rust

fn hello()  {
    thread::spawn(|| println!("Hello from thread 1"));
    thread::spawn(|| println!("Hello from thread 2"));
}

Or waiting for execution to end

fn hello()  {
    let t1 = thread::spawn(|| println!("Hello from thread 1"));
    let t2 = thread::spawn(|| println!("Hello from thread 2"));

    // Wait for both threads to complete
    t1.join().expect("t1 failed");
    t2.join().expect("t2 failed");
}

Using thread::scope

fn hello()  {
    thread::scope(|s| {
        s.spawn(|| println!("Hello from thread 1"));
        s.spawn(|| println!("Hello from thread 2"));
    });
}

Also

Because rust knows that threads do not escape scope:

  • Lifetime rules are simpler
  • We can borrow variables from the outer scope
fn hello()  {
    let n = 10;
    let mut m = 10;
    thread::scope(|s| {
        s.spawn(|| {
            m = m + 1;
            println!("Hello from thread 1, n = {n}")
        });
        s.spawn(|| println!("Hello from thread 2, n = {n}"));
    });
    println!("{m}");
}