Õ¾ÄÚËÑË÷: ÇëÊäÈëËÑË÷¹Ø¼ü´Ê
µ±Ç°Ò³Ãæ: ͼÊéÊ×Ò³ > Java Threads, Third Edition

2.6 Threads and Objects - Java Threads, Third Edition

Previous Section  < Day Day Up >  Next Section

2.6 Threads and Objects

Let's talk a little more about how threads interact. Consider the RandomCharacterGenerator thread. We saw how another class (the SwingTypeTester class) kept a reference to that thread and how it continued to call methods on that object.

Although those methods are defined in the RandomCharacterGenerator class, they are not executed by that thread. Instead, methods like the setDone( ) method are executed by the Swing event-dispatching thread as it executes the actionPerformed() method within the SwingTypeTester class. As far as the virtual machine is concerned, the setDone() method is just a series of statements; those statements do not "belong" to any particular thread. Therefore, the event-dispatching thread executes the setDone() method in exactly the same way in which it executes any other method.

This point is often confusing to developers who are new to threads; it can be confusing as well to developers who understand threads but are new to object-oriented programming. In Java, an instance of the Thread class is just an object: it may be passed to other methods, and any thread that has a reference to another thread can execute any method of that other thread's Thread object. The Thread object is not the thread itself; it is instead a set of methods and data that encapsulates information about the thread. And that method and data can be accessed by any other thread.

For a more complex example, examine the AnimatedCharacterCanvas class and determine how many threads execute some of its methods. You should be comfortable with the fact that four different threads use this object. The RandomCharacterGenerator thread invokes the newChar() method on that object. The timing thread invokes the run() method. The setDone() method is invoked by the Swing event-dispatching thread. And the constructor of the class (i.e., the default constructor) is invoked by the main method of the application as it constructs the GUI.

The upshot of this is that you cannot look at any object source code and know which thread is executing its methods or examining its data. You may be tempted to look at a class or an object and wonder which thread is running the code. The answer — even if the code is with a class that extends the Thread class — is that any of potentially thousands of threads could be executing the code.

2.6.1 Determining the Current Thread

Sometimes, you need to find out what the current thread is. In the most common case, code that belongs to an arbitrary object may need to invoke a method of the thread class. In other circumstances, code within a thread object may want to see if the code is being executed by the thread represented by the object or by a completely different thread.

You can retrieve a reference to the current thread by calling the currentThread() method (a static method of the Thread class). Therefore, to see if code is being executed by an arbitrary thread (as opposed to the thread represented by the object), you can use this pattern:

public class MyThread extends Thread {

    public void run( ) {

         if (Thread.currentThread( ) != this)

            throw new IllegalStateException(

                            "Run method called by incorrect thread");

         ... main logic ...

    }

}

Similarly, within an arbitrary object, you can use the currentThread() method to obtain a reference to a current thread. This technique can be used by a Runnable object to see whether it has been interrupted:

public class MyRunnable implements Runnable {

    public void run( ) {

        while (!Thread.currentThread( ).isInterrupted( )) {

            ... main logic ...

        }

    }

}

In fact, the Thread class includes a static method interrupted() that simply returns the value of Thread.currentThread( ).isInterrupted(), but you'll often see both uses within threaded programs. In examples in later chapters, we use the currentThread() method to obtain a thread reference in order to invoke other methods of the Thread class that we haven't yet examined.

    Previous Section  < Day Day Up >  Next Section