Concurrent Programming in Java

Perhaps the biggest problem facing concurrent programming today is the ‘herding of cats’ required to force programmers to adopt concurrent programming models. That, and concurrent programming is plain old difficult.

However, there are winds in the air that modern CPU architecture will finally force us to use concurrent programming. As it turns out, these winds are what has propelled good programmers all along; the desire to write a program that runs well on current hardware. To avoid bloat. To be efficient. And small.

As Java programmers, and more loosely as object oriented programmers, the desire to be re-usable (as OO programmers) and the desire to show that Java is superior (let’s face it, it is) similarly propels us to do our best to embody the principles of OO programming.

So let’s get to the point. Java doesn’t have an easy way to do Threads. You have to make all these complex checks and balances and it’s just a big bother, isn’t it? Plus, if you do design or think about program flow, it’s all too easy to visualize program flow as a straight line. A = 1, B = 2, A + B = 3. No one thinks about setting A and B at the same time. Why? Besides not perceiving a need (due to outdated, single-core hardware), one answer could be speed.

Setting A and B might take less than a handful of nanoseconds on a fast computer, but starting a new thread takes time. On my i7 system, I timed the creation-to-execution time and main program impact of 1 million threads. Every time I created a thread it cost my program about 35 milliseconds. Additionally, each thread began executing approximately 18 milliseconds after it was created. Obviously, creating a thread just to add two numbers at the same time is a waste of CPU time. Secondarily, you would need to wait for both threads to finish executing before you added the numbers. So all-in-all, calculating when you should use concurrent programming is a really big headache.

Incidentally this is also why the “sufficiently smart compiler” will never exist; calculating execution time can’t be done in advance. CPUs might be slower or faster, it’s based on real-time and not on some variable which can be known ahead of time.

So what do we know?

a) Concurrent Programming takes a small amount of time to set up (around 50 milliseconds on an i7, on average).
b) It’s easiest to use for small, independent, “fire and forget” tasks that don’t need to be synchronized with the main program.

Have any lightbulbs flashed yet? Well, let me tell you a story.

I was writing code on my Kongzi project, and it kept crashing in the UI thread, which locked up the program itself. I had to open task manager to close it which was a pain. I realized that I was committing a mortal sin of the UI world; I was doing extensive processing in the UI thread. The user would click a button, and the UI thread would fire the button event, which would take the software on a merry romp through CPU land. This was unacceptable, but I didn’t realize I was doing it. Later on, had I put the code into production, the UI would have seemed unresponsive and sluggish under more stressful “normal” use conditions.

So I decided to use a new thread to process the data and “return” immediately. After all, clicking the button just tells the program what to do. We don’t need to freeze up the UI thread each time.

It turned out to be a genius idea. I created a method like this:

// This function does whatever you want -- in a thread!
public void doWhatever()
{
        (new Thread() {
                public void run() {
                        // Thread Code Goes Here
                }
        }).start();
 // return immediately!
        return;
}

Now notably, such a method can’t return any data (but it can modify global variables), since it does everything in a thread. But it’s perfect for updating status labels, for auto-saving, for printing, for doing any kind of complex task that you don’t want to do in the UI thread. One example can be logging. If you need to institute extensive logging, using a method like the above will return in about 35 miliseconds. No I/O time will be added to the main program. There are surely many applications for this in gaming as well; adding a thread which changes the status of an object over time, and exits on it’s own after a predictable length of time, is an easy way to code simple physics like gravity. Say, for a mario-world/2d platform game. Shots from a spaceship, for example, could be controlled by a thread. This would clean up your game loop considerably.

Now, you normally wouldn’t want to create one thread for each force vector on an object, for example, because 35 miliseconds of game loop time is a lot; that would be only about 30 “shots” which could be fired, or 30 objects created, forces applied, etc. per second. This could have disastrous effects on a program which requires 60fps or higher. Never fear; Have a monitor thread that creates threads for you! If it’s backlocked, it can clone itself and work twice as fast. What it does is monitor a queue and create threads. So you just “list.add(“object name”); for example, and the little helper threads go crazy doing their little thing. It all seems so simple now! The only problem would be locking the list so only one helper thread can pull a value off of it at a time. That’s not really a problem. Use the volatile keyword. “public int”? “public volatile int”! No problem. Use a synchronized block of code. Use a SynchronizedList. No problem! The point is that it will take far less than 35 miliseconds to add data to a list and pull it off again. This kind of simple messaging will help you return values from methods which run in threads as shown above.

In short, threads aren’t really that difficult or time consuming. They can really help. And sometimes they’re even required to achieve certain effects.

I’ll be able to post some more specific examples of this in a bit. Right now, I have to go to work. Sayounara!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: