I'm no expert and I couldn't find anything online either. I'm probably doing the same subject as you at uni and here's what I came up with (speaking from personal experience).
The issue locks pose to the principle of abstraction is that the state of a lock and its resources may not be determinable by the state of the currently executing instruction set. For example, in C++ you could have a Baker class, that requires mutually-exclusive access to some Oven object. The Baker needs to use the oven quite often (open/close/put things inside) and requires exclusive access to an Oven to do so, however this cannot be truly abstracted as when exactly he requires this mutually-exclusive access may matter to his function.
We may need to add functionality to our system that is separate to the Baker, but requires mutually-exclusive access to the same Oven the baker is using. In implementing these changes, due to how locks depend on the state of multiple threads at once, we are not assured that the behaviour of the previously-abstracted Baker class will remain the same in the runtime of our programs. (EG: If the oven is being used by another thread, the baker might decide to wait 30 minutes before checking to see if the Oven is free again, which may be unwanted, inefficient behaviour).
Due to the same issues, locks also violate the principles of composability as different components of a program cannot be seamlessly composed if they all depend on each other’s potentially undefined behavior in a multi-threaded application.
Hope that helps - let me know your thoughts so we can ace this together.