We can use a simple crude model of a standard processor
to illustrate the concepts involved in threading.
When a program runs, the registers contain the current
state of execution, which includes a pointer to the memory address
of the next instruction.
When the program flow jumps to another location, as when a method
call occurs, the current register values are saved on a stack and
a new next-instruction-address, as well as other register values
are loaded.
When the flow returns to the original location, the old register
values are popped off the stack and loaded back into the registers.
Note: to allow for many layers of
method calls, the stack should be as large as possible.
Multi-threading involves maintaining more than one stack and switching
between them.
This diagram illustrates multi-threading:
A separate stack in this case is maintained for each thread.
Suppose Thread 1 represents the initial process flow. At some point,
determined by the multi-processing architecture, the processing
is stopped, and the current registers are saved on the Thread 1
stack.
The top of the Thread 2 stack replaces the registers and then the
processing continues.
At a later point in time, the processing stops again and the current
registers are saved on the Thread 2 stack. The Thread 3 stack values
are popped off and put into the registers and then processing continues.
This switching in and out of the different thread stacks proceeds
in this manner until the program finishes. Individual threads may
finish during the processing and new ones created.
The details of particular hardware and virtual processor will vary
but the general principle here of saving the state of a process
and replacing it with the state of a separate process, is the essence
of threading (and multi-processing) on a single processor system.
Note that the JVM
does not use a model based on multiple registers. Instead, the JVM
uses a stack frame processing model. Whenever a method is
invoked, its state (values of the method variables and a pointer
to the next instruction) is placed on the stack. If this method
in turn invokes another method, then the new method frame is placed
on top of the stack and it executes.
Each thread has a stack of such a method frames as one method
invokes another. The total frame stack will be saved when a new
thread displaces it. .
Last update: Feb.28.04
|