Threads

What we want to achieve is concurrency. Why? - Responsivity - Efficiency - Ecological validity

On a machine with two CPU’s there can be real parallelism, one one machine concurrency. JVM has a scheduler that will manage threads, processor time etc

What is thread?

A thread is a sequential execution of processing tasks of an application. Every thread has its own stack but shared memory. There are also methods to exchange info between threads. the static main function of a class does start a new main thread.

Life cycle of a thread

When a thread is instantiated and started, it will be scheduled by the scheduler. The scheduler can change the status to ready, runnung, yield, blocked or finished.

Examples

There are two ways how a multi-thread application can be implemented. A class can either implement the interface Runnable or extend the class Thread .

class MyRunnableClass implements Runnable {
    private volatile boolean stopRunning = false;

    public void run(){
        while (keepRunning){
            System.out.println("Up and running");
            try{
                Thread.sleep(1000);
            } catch (InterruptedException e){
                e.printStackTrace();
            }
        }
    }

    public void stop(){
        stopRunning = true;
    }

    public static void main (String[] args) throws InterruptedException{
        MyRunnableClass instance = new MyRunnableClass();
        Thread t = new Thread(instance);
        t.start();
        for (int i = 0; i < 10; i++){
            Thread.sleep(1000);
        }
    }
}

// Alternative
class MyThreadClass extends Thread {
public static void main (String[] args) throws InterruptedException{
        MyThreadClass instance = new MyThreadClass();
        instance.start(); // call to Threads empty or, if implemented, overriding MyThreadClass run()-method  
        for (int i = 0; i < 10; i++){
            Thread.sleep(1000);
        }
        instance.stop(); 
    }
}

Interference

One of the known issues of multithreading is interference. This means that access of one object by two objects of different threads can lead to errors. Examples are: - Two instances of the same runnable player class access the same help class sequencegen - An instance of the runnable class Waiter and an instance of the runnable class Cook access the same class Kitchen.

One can differentiate between thread-safe and race condition. Thread safe means that a program is independent of the time of the execution of its threads. Race condition means that the correctness of a program depends on the timing of the program. Correct means that all class invariants (i.e. conditions) and contracts are fullfilled. Solution for this problem is synchronization.

// synchronized method
public synchronized void inc() {i++;}
// synchronized block
public void inc() {synchronized (this) {i++;}}

//works per object, not per class!!!

Volatile

If we use an ordinary boolean to test whether a thread should be kept running, it might be that the thread never stops because the boolean is cached and changes won’t work through. Therefore we need to declare the variable volatile. By doing so it will never be cached thread-locally but kept in main memory.