[Talib]: we have ensured that we avoid any static or instance variables (wherever possible) Hmmm... "ensure" sounds fairly absolute, but "wherever possible" sounds kind of vague. If there are places where your objects are accessible through anything other than local variables, then that's a possible concern for thread safety.
As you correctly note, local variables are themselves inherently thread-safe, but the objects they refer to are not necessarily thread-safe, if they are referenced by other threads in any way.
[Talib]: so that we do not need to synchronize (to improve performance). I've seen a lot of poorly-written, unsafe code committed in the name of "improving performance". And in many cases, synchronization is
not a big problem. Sometimes it is, true, but please don't assume that's the case without specific reason. Synchronization can be extremely useful; please don't avoid it entirely just because you've heard that it
can be a performance problem.
Also, you say you "avoid" static or instance variables. Does this include the various objects whose safety you're now worrying about? If you have
no static or instance variables, then I would say you are completely thread-safe. If the objects have class or instance variables (as most do), then you may have a problem. But from your description, it's hard to tell if this is the case or not.
[Talib]: If yes, do I need to synchronize all the code which is multithreaded and where I am doing any operations on these objects? I have thousands of line of multi-threaded code in my application...putting all of it in synchronized blocks will impact my application's performance drastically...how should I go about this? There are a variety of possible answers to this, and in general it requires careful analysis of the code you're dealing with. Synchronization is one possible answer, but not the only one. Often the simplest way to make a class thread-safe is to make it immutable. If that doesn't work, then the second-simplest is to make all the methods synchronized. But that doesn't always work, e.g. if you mix mutable static and mutable instance data, or if you give your classes a crappy overly-find-grained API like those of Vector or StringBuffer (where the synchronization provided by Sun is next to useless). Other solutions possible in JDK 5 and later include volatile, atomic classes, and java.util.concurrent locks. If you can't isolate the data in each thread, then I recommend
Java Concurrency in Practice as an excellent way to learn more about this topic.