synchronising concurrent code in this diagram the producer is running in its own thread (although it could also run in separate processand places data onto some common shared data container subsequently number of independent consumers can consume that data when it is available and when they are free to process the data howeverthere is no point in the consumers repeatedly checking the container for data as that would be waste of resources (for example in terms of executing code on processor and of context switching between multiple threads or processeswe therefore need some form of notification or synchronisation between the producer and the consumer to manage this situation python provides several classes in the threading (and also in the multiprocessinglibrary that can be used to manage critical code blocks these classes include lockcondition and semaphore python locks the lock class defined (both in the threading and the multiprocessing librariesprovides mechanism for synchronising access to block of code the lock object can be in one of two states locked and unlocked (with the initial state being unlockedthe lock grants access to single thread at timeother threads must wait for the lock to become free before progressing the lock class provides two basic methods for acquiring the lock (acquire()and releasing (release()the lock when the state of the lock object is unlockedthen acquire(changes the state to locked and returns immediately when the state is lockedacquire(blocks until call to release(in another thread changes it to unlockedthen the acquire(call resets it to locked and returns the release(method should only be called in the locked stateit changes the state to unlocked and returns immediately if an attempt is made to release an unlocked locka runtimeerror will be raised an example of using lock object is shown below