Intro to Writing Multithreading in Java

jzfrank

jzfrank

Posted on January 16, 2023

Intro to Writing Multithreading in Java

Multithreading is like creating a new branch that runs independently and uses common resources (different from multiprocessing, which creates new memory address for each process).

There are mainly two approaches for writing multithreading in Java. In this tutorial, we are going to demonstrate it by writing classes that counts from 0 to 2. Each sleeping 1 second. The interesting part is, we want to run many threads that doing the exactly the same thing.

Extends Thread class

public class MultithreadingThingByExtendingThreadClass extends Thread {
    private int threadNumber;

    public MultithreadingThingByExtendingThreadClass(int threadNumber) {
        this.threadNumber = threadNumber;
    }

    @Override
    public void run() {
        for (int i=0; i<3; i++) {
            System.out.println(i + " from thread (ExtendingThreadClass) " + threadNumber);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // do nothing
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

In test driver:

public class TestDriver {
    public static void main(String[] args) {
        System.out.println("Testing MultithreadingThingByExtendingThreadClass");
        for (int i=0; i<5; i++) {
            MultithreadingThingByExtendingThreadClass m =
                    new MultithreadingThingByExtendingThreadClass(i);
            m.start();
        }

    }
}
Enter fullscreen mode Exit fullscreen mode

Here, m.start() will start a new thread. The output will be something like this:

Testing MultithreadingThingByExtendingThreadClass
0 from thread (ExtendingThreadClass) 4
0 from thread (ExtendingThreadClass) 2
0 from thread (ExtendingThreadClass) 1
0 from thread (ExtendingThreadClass) 0
0 from thread (ExtendingThreadClass) 3
1 from thread (ExtendingThreadClass) 4
1 from thread (ExtendingThreadClass) 1
1 from thread (ExtendingThreadClass) 2
1 from thread (ExtendingThreadClass) 3
1 from thread (ExtendingThreadClass) 0
2 from thread (ExtendingThreadClass) 1
2 from thread (ExtendingThreadClass) 3
2 from thread (ExtendingThreadClass) 0
2 from thread (ExtendingThreadClass) 4
2 from thread (ExtendingThreadClass) 2
Enter fullscreen mode Exit fullscreen mode

We observe the order of running threads is not the order of creation of threads.

Note here if we use m.run() instead of m.start(), we will finish current thread first, after which we begin a new thread. That breaks the point of multithreading, isn't it?

To see this, change m.start() to m.run()

public class TestDriver {
    public static void main(String[] args) {
        System.out.println("Testing MultithreadingThingByExtendingThreadClass");
        for (int i=0; i<5; i++) {
            MultithreadingThingByExtendingThreadClass m =
                    new MultithreadingThingByExtendingThreadClass(i);
            m.run();
        }

    }
}
Enter fullscreen mode Exit fullscreen mode

This is what we get:

Testing MultithreadingThingByExtendingThreadClass
0 from thread (ExtendingThreadClass) 0
1 from thread (ExtendingThreadClass) 0
2 from thread (ExtendingThreadClass) 0
0 from thread (ExtendingThreadClass) 1
1 from thread (ExtendingThreadClass) 1
2 from thread (ExtendingThreadClass) 1
0 from thread (ExtendingThreadClass) 2
1 from thread (ExtendingThreadClass) 2
2 from thread (ExtendingThreadClass) 2
0 from thread (ExtendingThreadClass) 3
1 from thread (ExtendingThreadClass) 3
2 from thread (ExtendingThreadClass) 3
0 from thread (ExtendingThreadClass) 4
1 from thread (ExtendingThreadClass) 4
2 from thread (ExtendingThreadClass) 4
Enter fullscreen mode Exit fullscreen mode

We can see how threads are executed sequentially instead of parallelly.

One worth mention drawback of this approach is that Java doesn't allow multi-inheritance, so we cannot extend other classes.

To remedy this, another approach is implementing Runnable interface, as Java does allow implementing many interfaces.

Implementing the Runnable Interface

public class MultithreadingThingByImplementingRunnableInterface
implements Runnable
{

    private int threadNumber;

    public MultithreadingThingByImplementingRunnableInterface(int threadNumber) {
        this.threadNumber = threadNumber;
    }

    @Override
    public void run() {
        for (int i=0; i<3; i++) {
            System.out.println(i + " from thread (ImplementingRunnableInterface) " + threadNumber);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // do nothing
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

However, when we write testdriver, we do it a bit differently. We need to create a thread ourselves, and wrap the stuff inside:

public class TestDriver {
    public static void main(String[] args) {

        System.out.println("Testing MultithreadingThingByImplementingRunnableInterface");
        for (int i=0; i<5; i++) {
            MultithreadingThingByImplementingRunnableInterface m =
                    new MultithreadingThingByImplementingRunnableInterface(i);
            Thread myThread = new Thread(m);
            myThread.start();
        }

    }
}
Enter fullscreen mode Exit fullscreen mode

We get just the same output:

Testing MultithreadingThingByImplementingRunnableInterface
0 from thread (ImplementingRunnableInterface) 2
0 from thread (ImplementingRunnableInterface) 3
0 from thread (ImplementingRunnableInterface) 4
0 from thread (ImplementingRunnableInterface) 0
0 from thread (ImplementingRunnableInterface) 1
1 from thread (ImplementingRunnableInterface) 0
1 from thread (ImplementingRunnableInterface) 2
1 from thread (ImplementingRunnableInterface) 4
1 from thread (ImplementingRunnableInterface) 3
1 from thread (ImplementingRunnableInterface) 1
2 from thread (ImplementingRunnableInterface) 0
2 from thread (ImplementingRunnableInterface) 4
2 from thread (ImplementingRunnableInterface) 2
2 from thread (ImplementingRunnableInterface) 3
2 from thread (ImplementingRunnableInterface) 1
Enter fullscreen mode Exit fullscreen mode

Reference

Coding with John

💖 💪 🙅 🚩
jzfrank
jzfrank

Posted on January 16, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related