Sitemap

Advanced Python 6 — Thread Lifecycle & Difference between start() and run()

3 min readFeb 4, 2026

--

What is a Thread Lifecycle?

The thread lifecycle describes the different stages a thread goes through from creation to completion.

Get Abhishek Jain’s stories in your inbox

Join Medium for free to get updates from this writer.

In Python, a thread goes through these main stages:

  1. New
  2. Runnable
  3. Running
  4. Waiting / Blocked
  5. Terminated

Let’s understand each one.

Press enter or click to view image in full size
Press enter or click to view image in full size
Press enter or click to view image in full size
Press enter or click to view image in full size
Press enter or click to view image in full size

Example:

import threading
import time

def task():
print("[Running] Thread is now running")

print("[Waiting] Thread going to sleep (waiting state)")
time.sleep(2)

print("[Running] Thread resumed after sleep")
print("[Terminated] Thread finishing execution")

print("[New] Thread object created")
t = threading.Thread(target=task, name="DemoThread")

print("[Runnable] Thread is about to start")
t.start()

print("[Main] Waiting for thread to finish")
t.join()

print("[Dead] Thread has terminated")

Difference Between start() and run()

start() Method

What it does

  • Creates a new thread
  • Calls run() internally
  • Runs code concurrently
import threading

def task():
print("Running in a separate thread")

t = threading.Thread(target=task)
t.start()

✔ New thread is created
✔ Runs in parallel (logically)
✔ Correct way to start a thread

run() Method

What it does

  • Runs the function like a normal function
  • Does NOT create a new thread
t = threading.Thread(target=task)
t.run()

❌ No new thread
❌ Runs in the main thread
❌ No concurrency

Press enter or click to view image in full size

EXAMPLE

import threading
import time

def task():
print(f"Task running in thread: {threading.current_thread().name}")
time.sleep(1)
print(f"Task finished in thread: {threading.current_thread().name}")

print("Main thread:", threading.current_thread().name)

print("\n--- Using start() ---")
t1 = threading.Thread(target=task, name="Worker-Thread")
t1.start()
t1.join()

print("\n--- Using run() ---")
t2 = threading.Thread(target=task, name="Fake-Thread")
t2.run()

print("\nBack to main thread:", threading.current_thread().name)


### OUTPUT
Main thread: MainThread

--- Using start() ---
Task running in thread: Worker-Thread
Task finished in thread: Worker-Thread

--- Using run() ---
Task running in thread: MainThread
Task finished in thread: MainThread

Back to main thread: MainThread

Final Takeaway

  • A thread goes through creation → execution → waiting → termination
  • start() creates a new thread
  • run() is just a normal function call
  • Always use start() for real multithreading

start() gives you concurrency; run() does not.

--

--