That's a very concise example to get to this discussion. When you make two objects and put them on two threads, each instance only has to work on a single
thread. That's the easy way to do things - a "non-threadsafe" approach.
When you run two threads with the same instance of your runnable the JVM is allowed to run one line of code for thread 1 and another line of code for thrad 2, and can even break up parts of lines. So if you do something as simple as:
you can be surprised to find that another thread changed memberVar to 437 in between those lines. If you know a class will be used this way, or you want to make it possible, you have to make it thread safe.
You have to think about any resources that might be shared by two threads in the same object instance. Member variables, any other external objects that both threads might reference, etc. It's likely you'll want to synchronize methods or code blocks (prefer code blocks) that access such shared resources.
If each thread needs its own variables or resources or whatever, make them as local variables. Each thread gets its own set of local variables on the stack.
Any of that make sense?