In this preceding code example, we define a function, threadWorker, which will be the invocation target of the thread that we will create. All that this threadWorker function does is to print out its current state, and then sleep for 10 seconds by calling time.sleep(10).
After we've defined threadWorker, we then go on to create a New Thread object in this line:
myThread = threading.Thread(target=threadWorker)
At this point in time, our thread object is currently in the New Thread state, and hasn't yet been allocated any system resources that it needs to run. This only happens when we go on to call this function:
myThread.start()
At this point, our thread is allocated with all of its resources, and the thread's run function is called. The thread now enters the "Runnable" state. It goes on to print out its own state, and then proceeds to block for 10 seconds by calling time.sleep(10). During the 10 seconds that this thread sleeps, the thread is considered to be in the "Not-Running" state, and other threads will be scheduled to run over this thread.
Finally, once the 10-second period has elapsed, our thread is considered to have ended and be in the "Dead" state. It no longer needs any of the resources that it was allocated, and it will be cleaned up by the garbage collector.