If you use your second approach, putting the locking logic in the thread, then every time you need a different task to access that resource, you have to add locking code to the new task.  And if any of the tasks that touch that resource don't perform locking or mess up how they do it, then the resource can become corrupted. This is going to result in a brittle application where adding a feature can cause breakage if the person adding the code doesn't get the locking exactly right. It's also the opposite of DRY. 
With the first approach the object protects itself by implementing whatever locking is required to access it. Any threads accessing that object will have to acquire the lock specified by the class. There is no opportunity for any threads to bypass the locking on the resource. 
Using a dedicated lock, for instance using a private final instance member, can make it harder for unrelated code from being able to acquire the lock on the object. Malicious code could still use reflection but it would prevent accidental access. 
Using a class level lock prevents more than one thread from accessing the resource even if there are multiple resources. You could make a bottleneck this way.