Is Java's HashMap thread-safe? Explain why or why not. How does ConcurrentHashMap achieve thread safety and performance (e.g., lock striping, CAS operations, non-blocking reads, tree bins under high collisions, resizing strategy) in modern JDKs? Discuss typical pitfalls and when to prefer each.