run() выполняет код синхронно в том потоке, который вызвал метод. Новый Java thread и новый OS thread при этом не появляются.
start() переводит объект Thread в состояние запуска, после чего JVM создаёт отдельный путь выполнения и вызывает run() уже там. Момент, когда новый поток получит CPU, не определён, поэтому код после start() не должен рассчитывать на конкретный порядок выполнения.
Подробнее: Потоки в Java: Thread, start(), interrupt(), sleep() и join().