Tuesday, January 13, 2009

Basic Java Thread Exercises

Was this helpful for you? Please take a little time to comment on the exercises and solutions after you've used them, I'd like feedback from you. Thanks! =)

UPDATE 12/03/20011: Fixed broken download links

Thread Race
Thread Relay Race

Assassin Thread Slayer


This brief, simple tutorial assumes you already know the basic use of OOP in Java language.

Basic Theory Background - What is a thread?

I like to take the approach form the Operating Systems perspective, where a thread defines a single execution unit in a process, being a process an instance of a program in a multitasking environment.

Meaning, for example, when I run my internet browser, it is a process, and each separate browsing window tab inside that browser is a thread.

Threads, ideally, are independent execution units; they don't depend on others to execute, and a process can go on separately from the thread.

However, this would work fine in a multi-processing environment, like in a server with several CPU's. Most operating systems are multi-tasking, meaning they emulate this multi-processing by reserving time slots and resources alternately for each process, and as the CPU clock speed is high, it is transparent for the user.

Think about your computer now: you probably have this browser window open and also maybe your personal messenger, and maybe playing some music. Well they are executing alternately in the background, but for you as a user it's seamless.

And even in a multi-processing environment, threads may be having access to a resource another thread may be using, and this can cause what is called a deadlock; when neither thread can have access to a resource.

Imagine for example me and my brother want to wash our cars, and there's only one bucket and one sponge. Let's say I got the sponge and my brother the bucket: I won't be able to start washing my car because I'm waiting for the bucket, but my brother won't give it away because he's waiting for the sponge, so we're both just standing there looking at each other to see who releases his item first, but no one does, and I'm late for my date =(

If we were an harmonious family, we'd agree to share both alternately; he'll be using the bucket and sponge while I'm removing the soap from the part of the car I've washed and dry it, and then ask him for the bucket and sponge when done and he'll dry his part of the car and then ask me for the bucket when done and so on... and I'll be on time for my date with a shining car =D

What I mean is that when we program threads, we must consider these possibilities and provide our classes with a mechanism to manage shared resources. Java itself includes several synchronization methods for that purpose.


The purpose of this post is to provide exercises that will help practice a basic implementation of threads. Here we'll present the problem and guide through the solution from a design approach, the implementation is up to you, and that's what these exercises are about: use what you've learned about threads implementation in Java for coding the solution. Good luck with your self-assessment exams! :-)

Exercise 1 - Thread Subclassing Vs Runnable Implementation - The Thread Race.

I wanted to make an interesting experiment: is it true that threads run independently, and that in multi-tasking environments each execution unit is given a time slot based on certain algorithms? What will happen if I made a thread race, let's say 10 threads... will the first one being run will finish first, or are they completely asynchronous and independent?

Let's make a thread race program, where a ThreadRace class will create an instance of 10 ThreadRaceCompetitor's. Then it'll run them all. There will be a results class called ThreadRaceContext, which will keep the scorecard of who finished in which place.

When a ThreadCompetitor finishes the race, it will have to inform the ThreadRaceContext his race number, and that it's done, so the ThreadRaceContext will inform about its arrival. Who'll arrive first? Make your bets!

Design challenges: The ThreadRaceContext object is a common resource for all ThreadCompetitor's. How can I make sure it keeps an accurate record of each of their positions at the race?

How should I implement the solution of I extended from Thread rather than implementing the Runnable() interface? What will the difference be? How would the ThreadRace class control each of the threads execution?

Reference for solving this exercise.

Exercise 2 - Synchronizing the Threads Through the join() Method - The ThreadRelayRace

Now let's make the Thread Race even more interesting: let's make it a ThreadRelayRace, in which the competition will occur between 10 ThreadRelayRaceTeam's, each of them composed of 4 ThreadCompetitor's.

Now the ThreadCompetitors will have a thread number and a team number, and the ThreadRaceContext will inform when a ThreadRaceCompetitor from a team finished, and then the whole team finishes, informing the results of the team's positions.

Design challenges: Did you make the previous classes reusable? How would I redesign the ThreadRaceCompetitor and the ThreadRaceContext to comply with these changes?

Now the ThreadRace will start running the ThreadRelayRaceTeam, and the ThreadRelayRaceTeam will start running its ThreadRaceCompetitor #1. How can I ensure the ThreadRaceCompetitor #1 starts and then follows #2 using the join() method?

Reference for solving this exercise.

Exercise 3 - Reserving a Shared Resource Using the interrupt() Method - The Assassin Threads Slayer.

So I decided to make an experiment in which I want to see that will happen if I place 10 AssasinThread's in a ThreadSlayerRoom, where there's only one ThreadKillerGun? Who'll take the gun first and kill all others?

The AssasinThreadSlayer class will make sure the AssasinThreads are placed on the ThreadSlayerRoom where the fun will start when their run() method is invoked. They'll all try to get the ThreadKillerGun first, and if it's already taken, they'll say it: "Assassin 1: Oh No! Gun's Taken!"

You should be informed who takes the gun and how all AssasinThread's are being killed one by one.

Design Challenges: Who will call the interrupt for the AssasinThread's when one takes the gun? It has to be the gun.

Reference for solving this exercise.

A Reference Code Example.

A useful code example implementing all the methods included in this exercise.

Was this helpful for you? Please take a little time to comment on the exercises and solutions after you've used them, I'd like feedback from you. Thanks! =)