Unity (and all the common containers) are guaranteed (by their designers) to be thread-safe (or at least, sort of) in case of parallel resolves with no registrations. In other words, as long as you separate the registration phase from the resolve phase, and from one point on only resolve from the container, you can call Resolve
in parallel from multiple threads without problems.
As a matter of fact, as a best practice, you should always strictly separate the registration phase from the resolve phase, because this will lead to serious trouble and very hard to find race conditions.
This separation of those phases is so important, that some DI libraries (such as Autofac and Simple Injector) force this pattern upon you (where Simple Injector is the strictest of the two). The Simple Injector documentation contains a very clear explanation on why Simple Injector forces you upon this model and explains what could happen in case you would be able to change the configuration. To quote part of that explanation here (but you should definitely read the whole explanation):
Problems with thread-safety can easily emerge when the user changes a
registration during a web request. If the container allowed such
registration changes during a request, other requests could directly
be impacted by those changes (since in general there should only be
one Container instance per AppDomain). Depending on things such as the
lifestyle of the registration; the use of factories and how the object
graph is structured, it could be a real possibility that another
request gets both the old and the new registration. Take for instance
a transient registration that is replaced with a different one. If
this is done while an object graph for a different thread is being
resolved while the service is injected into multiple points within the
graph - the graph would contain different instance of that abstraction
with different lifetimes at the same time in the same request - and
this is bad.
As I see it, that the article you are linking goes more into the difference between the Service Locator anti-pattern and applying Dependency Injection correctly, which means only accessing the container inside your Composition Root. The writer of that article (Larry Spencer) isn't very clear, but inside his Composition Root, he creates one single Unity container and uses it for the duration of the whole application. In a sense it is still 'global', but he prevents that instance from being accessed through the application (because that is the Service Locator pattern).
Although the writer tries to create a thread-safe wrapper around the Unity container, his attempt is naive. What he does is creating a lock around every Register
and Resolve
method. Not only will this give enormous congestion in multi-threaded applications, it doesn't address the problems of what happens when registering and replacing instances after object graphs have already been build and cached, as both the Simple Injector documentation explains and this Unity question shows.