When the run method is called directly, the method simply executes in the current thread instead of as its own thread.
In this example, the thread T1 directly calls run on two new instances of A, so both of these report the current thread as "T1." Then the start method is called on T3, which allows T3 to execute as its own thread.
So the output is T1T1T3.
"We're kind of on the level of crossword puzzle writers... And no one ever goes to them and gives them an award." ~Joe Strummer sscce.org
I think it has to do with the fact that the threads are being started with run() instead of start(). If you call the run() method directly it starts the thread in the current thread. If you call start() it spawns a new thread to run in.
The new A().run() prints T1 because that's what it was named in the main method of class C.
The new Thread(new A(),"T2").run(); prints T1 because it's actually run in the same thread (the T1 thread started by the main method of class C). I would assume the "T2" name is just dropped on the floor since it's going to run in an already existing thread that already has a name of T1.
The new Thread(new A(),"T3").start(); prints T3 because it's actually a new thread since start() is used instead of run().