Lesson 4

Threads I

Sometimes there is a need to do few things at the same time e.g. cheating during the exam and checking the position of the examiner. With a usage of threads different instructions can be executed concurrently (e.g. two loops are executed at the same time).

I. Thread Class


// Creating a new thread:
Thread thread0 = new Thread(new Runnable() {
    public void run() {
        // code
    }
});

// Let’s try to write the same but this time using lambda expression
Thread thread1 = new Thread(() -> {
    // code
});

// Thread has to be started.
// Creating an object is not enough.
thread0.start();
thread1.start();
Task 0

Create 2 threads. First will print digits from 0 do 9 with a usage of System.out, second will do the same but with a usage of System.err. Let those threads print 20 series of digits.

Use print method instead of println.

Execute the program few times. Are the results the same or different? Why?

Task 1

Create a loop which will print numbers from 0 to 1 000 000.

Next check how much time the program needs to be finished. You can use System.currentTimeMillis() method, that returns a number of milliseconds from 1st January 1970 0:00 UTC.

We are looking for the difference between the time before and after executing a loop.

Save time results for 3 attempts (e.g. on paper, in a text file)

Next create 2 threads. First one will print even numbers, second one will print odd numbers from the range [0,1 000 000].
Each thread will print how much time it needed to execute its loop.

Save time results for 3 attempts and compare them with the previous implementation (without threads).

II. Threds with frames

Task 2

Prepare a window drawing a rectangle of size 30x30 at point x, y.

x and y should be properties of frame class.

Create a new thread: increase x and y by 1 on every 100ms.

Task 3

Make the rectangle boucining of the window edges.

Tip: if x value is to big, the thread should change incrementation into decrementation.

III. Concurrent instructions executing


Task 4

Analyze the code below. What do expect as a result?

Execute the program few Times.

Which fragment is critical? Which thread cannot be interwaved with executing other thread.

Add a keyword "synchronized" in proper place (there are 2 possibilities).

class AddingThread extends Thread {

    private Counter c;

    public AddingThread(Counter c) {
        this.c = c;
    }

    public void run() {
        for (int i = 0; i < 1000; i++) {
            c.inc(i);
        }
    }
}

class Counter {
    private int x = 0;
    void inc(int value) {
        int sum = x + value;
        x = sum;
    }
    public String toString() {
        return x + "";
    }
}

public class Main {

    public static void main(String[] args) {
        Counter c = new Counter();
        AddingThread at0 = new AddingThread(c);
        at0.start();
        AddingThread at1 = new AddingThread(c);
        at1.start();
        AddingThread at2 = new AddingThread(c);
        at2.start();
        System.out.println("Counter.x=" + c);
    }
}
synchronized keyword
  1. It can be written before declaring returning type of a method.
  2. It can be used as a block.
  3. If synchronized is used then a block of instructions is treated as ”cannot be interrupted".
// synchronized for a method
public synchronized void method() {
    //...
}

// synchronized for an object
synchronized(object) {
    //...
}
Task 5

Create a class named Account(long balance). It is a representation of a bank account with the information about its balance.

Bank is an entity which contains its funds, sum of all accounts’ balances. Let’s say we have 2 accounts with balance 10 000 each.

Task is to do concurrently 8 transactions (on those 2 accounts) using random amount of money.

When all the transactions are calculated, sum of balances for all the accounts should be the same as at the beginning.