I can't see a compelling reason why you'd need to make GetHashCode thread-safe, and I could see it leading to deadlocks or at least lock convoys if you aren't careful; GetHashCode is called from a lot of places you might not expect.
What's more logical is that if you have multiple threads sharing a single Foo, those threads will need to synchronize their access to the Foo, so you simply don't have multiple threads calling GetHashCode at once (or any other method of Foo).
Correctly designing thread-safe classes can be a difficult exercise; unless you have a very good reason to require thread-safe instance members, I would choose not to do it. The vast majority of the .NET Framework itself does not have thread-safe instance members.
Finally, there really isn't such a thing as a class being universally thread-safe. You can synchronize every single instance member, but a consumer of your class can still mess it up if they don't understand the semantics. Making GetHashCode thread-safe implies that you are trying to account for every conceivable threading scenario, but even most thread-safe classes are only thread-safe for certain operations, and GetHashCode is not normally one of them.
I'll refer you to Eric Lippert's recent post on thread-safety; think about the content of this when using a phrase such as "Make Foo thread-safe."