Short answer, no, JSPs by default are not automatically thread safe. If you have instance variables that are modified from within the service section of a JSP, they will be shared by all requests causing concurrency issues. As Jothi implied, this is the same for servlets. Like with servlets, there is a mechanism that was supposed to help make your JSPs more thread safe this is the isThreadSafe property which can be set in a JSP page directive. This technique is akin to implementing the deprecated SingleThreadModel interface with a servlet. In fact, most containers implement thread safe JSPs by having the generated code implement this deprecated interface.
For servlets, this turned out not to be the greatest idea which is why SingleThreadModel is deprecated. It was not a good idea because, even when using it, it was possible to write a servlet that is not thread safe.
So, in short, you should avoid relying on the threadSafe directive in JSPs for the same reason that you should avoid using the deprecated SingleThreadModel interface in your servlets.
Avoiding scriptlets altogether is the currently accepted best practice. JSPs with no scriptlets will have no instance variables and will take you a long way toward having thread safe JSPs.
Local variables in a JSP cannot be read across instances. Instance variables however are. This is why it is usually not a good practice to have instance variables in a JSP, since they are not thread safe
I probably should have mentioned this before: A JSP is neither thread-safe nor un-thread-safe.
Just as you can't delare a hammer, knife, or bicycle to be safe or unsafe (unless, of course you're talking about a defective one), you can't say that the technology, JSP is or isn't thread-safe. It's what you do with it that makes it safe or unsafe.
JSP will happily give you enough rope to hang yourself.