The core algorithms are essentially the same. The ThreadLocalRandom uses the Java ThreadLocal construct to create a new Random variable for each thread. This guarantees that the calls from each thread will never conflict with each (no contention).
Take a look at this line from Random for comparison:
} while (!seed.compareAndSet(oldseed, nextseed));
When you ask for a next value, Random takes the old value and generates a new value. It then uses the AtomicLong.compareAndSet function to set the new value, only if the old value is still the one it used. If another thread had changed the value, the loop will run again (and again, until it's the only loop that's both get and set the value in one random number generation). Thus there is possible contention, and thus possible performance implications.
The ThreadLocalRandom, because it is guaranteed not to conflict, does not require atomic functions and thread-safe operations/locking.
There are some tradeoffs you would want to think about. Using one Random allows for one random number generator which is very useful if you want to use a single seed for your application. If you make only occasional calls to Random, so that conflicts are likely to be "rare" (not the normal case) then you might not worry about conflicts and the small individual impact to performance may not matter. If you're calling random hundreds of time per seconds across multiple threads, then you clearly want to use ThreadLocalRandom.