.NET delegates have a Target associated with them - this corresponds to the this reference used in non-static methods wrapped by those delegates.
In your case, you're using the ThreadStart delegate. If you explicitly create new ThreadStart(formInstance.YourMethodName, you can query its Target property, and see that it referes to the formInstance.
When the delegate is invoked, this Target value (if any) is passed as the first argument to the underlying method - what C# represents as this reference.
To understand this a bit better, IL (the .NET's intermediate language) doesn't actually have anything like this. It doesn't really care all too much whether your method is an instance method or a static method (note that the .NET type information does have this distinction, but not IL itself). Instead, C#'s this is passed as the first argument to any instance method (including property accessors etc.) - this is a bit of a simplification, because you can have different calling conventions, but it's good enough for the common case. So while you can't call an instance method with any this in C#, it's rather trivial in IL. The delegate's Invoke method can simply pass the Target value as the first argument and "simulate" the way C#'s this works.
As for good practices, avoid having any access to GUI elements from other threads. It's way too easy to cause cross-thread GUI manipulation by accident and get an exception. It's actually quite easy even if you maintain reasonable separation - data binding is also dangerous.