Today I had to explain it to few people, so I thought that it would be good to have a place to write it down, so I don't need to do it next time:)
Global.asax.cs includes a class (usually called Global) that inherits from HttpApplication. The hard part is that HttpApplication can only handle one request per time. The confusing part is that this class includes methods that should be executed just once per application lifecycle, and if HttpApplication is able to handle only one request per time, how is it possible that everything works, and how is it possible that IIS is able to handle multiple requests pert time?
First things first, methods like Application_Start, Application_End are called once per AppDomain lifecycle, programmer should not be concerned that they exist in a scope of a class (usually called Global) that can be created many times. So these methods are different than for example modules that are executed once per HttpApplication. And it leads us to a second thought, class that exists in Global.asax (usually called Global) should be treated as an ordinary class, it means that its object can be created and destroyed at any time.
When a new request is send to IIS, and Global class object is busy handling other request, IIS can create a new thread and create a new instance of Global class. IIS can create such thread, but doesn't have to, it can stack a request and wait to reuse Global object that will finish handling previous requests.
To make it even more complicated each AppDomain that was created by ASP.NET can have multiple Global objects, so it is extremely easy to 'configure' something wrong, especially when you use static keyword, or a singleton pattern! Now it is also important to notice that one application can run as many AppDomains, but it is not very useful configuration (in majority of cases), but one IIS can host multiple applications, and each of them 'should' run in a separate AppDomain.
Hope it clarifies something :)