The problem with thread contention in malloc comes down simply that the heap must be protected by a mutex of similar device whenever it is updated. If two threads update the heap simultaneously you will have a race condition. The same problem applies to new so there is no fundamental reason why one should have less contention than the next.
Having said that, there are a number of tricks to minimize contention. The first is to break the heap up into separate Arenas. Each Arena has its own lock. If a thread tries to allocate memory and the one Arena is locked, it just tries to allocate off the next Arena.
Frees will need to access the same Arena that was used for a malloc. This can also be optimized by place the pointer to be freed onto a free list. This can be done atomically. When next the Arena becomes unlocked, all the pointers on the free list will get freed properly.
These techniques help prevent but do not eliminate contention which means in a producer consumer threading model, you may be better off having the consumer pass pointers back to the producer where they can be reused or deleted as appropriate.