When it comes to behavioral awareness pretty much all application software is stateless (or clueless). Threads will repeatedly execute the same code path in servicing a path even after it has failed for the umpteenth consecutive time. No matter how intelligent software may appear to its users, in assisting them in their tasks, it is inherently dumb (or at least suffering from a severe and prolonged bout of amnesia).
The primarily reason for this is that code has no means to introspect on its execution behavior (and performance) beyond its immediate (current) method and call sites. Code needs to be able to introspect its own execution behavior (including direct/indirect call dependencies) as well as that of its called (methods) and their called methods and so on. In doing so it can define (and redefine) normal execution behavior of a method (and all the methods it calls) and use this to reason about variation in operation, determine the drivers of such variation and predict (immediate) future performance. This goes far beyond primitive software based circuit breakers which are generally applied at remote call exit points. What is the point having a thread in servicing a request pass down all the various layers only then to be (temporarily) blocked or incur an expensive and problematic exception at such a point because of an ongoing fault. If a thread is aware of its behavior (and is able to distinguish one from another) it should be able to automatically short circuit the execution much further up the caller chain (much closer to the entry point). It should be able to look at a method (or a partial call stack) and quickly predict whether execution of the method is going to involve the usage of a faulty component. To do that it needs to be able to ask the runtime what happens when this method executes. The “happens” should include the methods that are likely to be executed and the typical resource consumption in doing so.