• No results found

Timing with threads

So what is a thread? You can think of threads in Java programming just like threads

in a story. In one thread of a story, we have the primary character battling the enemy

on the front line, and in another thread, the soldier's family are getting by, day to day. Of course, a story doesn't have to have just two threads. We could introduce a

third thread. Perhaps the story also tells of the politicians and military commanders making decisions. These decisions subtly, or not so subtly, affect what happens in the other threads.

Threads in programming are just like this. We create parts/threads in our program

and they control different aspects for us. We introduce threads to represent these different aspects because of the following reasons:

• They make sense from an organizational point of view • They are a proven way of structuring a program that works • The nature of the system we are working on forces us to use them

In Android, we use threads for all of these reasons simultaneously. It makes sense, it works, and we have to use it because of the design of the system.

In gaming, think about a thread that receives the player's button taps for "left",

"right", and "shoot", a thread that represents the alien thinking where to move next, and yet another thread that draws all the graphics on the screen.

Programs with multiple threads can have problems. Like the threads of a story, if proper synchronization does not occur, then things go wrong. What if our soldier

went into battle before the battle or even the war existed? Weird!

What if we have a variable, int x, that represents a key piece of data that say three

threads of our program use? What happens if one thread gets slightly ahead of itself and makes the data "wrong" for the other two? This problem is the problem

of correctness, caused by multiple threads racing to completion, oblivious of each other—because they are just dumb code after all.

The problem of correctness can be solved by close oversight of the threads and

locking. Locking means temporarily preventing execution in one thread to ensure that things are working in a synchronized manner. It's like freezing the soldier from

boarding a ship to war until the ship has actually docked and the plank has been lowered, avoiding an embarrassing splash.

The other problem with programs with multiple threads is the problem of deadlock, where one or more threads become locked, waiting for the right moment to access x, but that moment never comes and the entire program eventually grinds to a halt.

You might have noticed that it was the solution to the first problem (correctness) that

is the cause of the second problem (deadlock). Now consider all that we have just

been discussing and mix it in with the Android Activity lifecycle. It's possible that

you start to feel a little nauseous with the complexity.

Fortunately, the problem has been solved for us. Just as we use the Activity class and override its methods to interact with the Android lifecycle, we can also use other classes to create and manage our threads. Just as with Activity, we only need to know how to use them, not how they work.

So why tell me all this stuff about threads when I didn't need to know, you would rightly ask. It's simply because we will be writing code that looks different and is

structured in an unfamiliar manner. We will have no sweat writing our Java code to create and work within our threads if we can do the following:

• Accept that the new concepts we will introduce are what we need to work

with in order to create an Android-specific solution to the problems related

to working with threads

• Understand the general concept of a thread, which is mostly the same as a story thread that happens almost simultaneously

• Learn the few rules of using some of the Android thread classes

Notice that I said classes, plural, in the third bullet. Different thread classes work

best in different situations. You could write a whole book on just threads in Android.

We will use two thread classes in this book. In this chapter, we will use Handler. In Chapter 7, Retro Squash Game, and Chapter 8, The Snake Game, we will use the Runnable class. All we need to remember is that we will be writing parts of our program that run at almost the same time as each other.

What do I mean by "almost"? What is actually happening is

that the CPU switches between threads in turn. However, this happens so fast that we will not be able to perceive anything but simultaneity.

A simple thread timer example with the