Search for synchronized in ShoppingCart. You'll fine a couple of spots that lock on cartLines, a few that lock in the class instance itself. But then no other hits.
However, tons of internal variables all need to be kept self-consistent with each other, so locking against just one or the other of those variables won't work. Additionally, there are accessor methods that return direct access to internal variables, without any locking on the return value(ShoppingCart.iterator() is a good example of this). This problem also applies to the internal helper classes. In addition, any external wrapper classes, like ProductPromoWorker, which have to mutate the cart, do no locking whatsoever. This can cause problems when multiple threads are trying to mutate the cart. Which could occur if someone clicks 'addtocart' multiple times(like, people don't realize you only need to click it once, or just decide to click it 5 times really fast in a row). This is causing us much grief. We have the 404 pages in our sites looking pretty. As part of this prettiness, they try to look just like the rest of the site. And, in the header, we have a cart status area. Displaying the status has to walk the items in the cart internally, but if this is occuring at the same time you're trying to add things to the cart, it falls over. I don't have a solution to this. The entire ShoppingCart subsystem bad in this regard.