def lock(self, key, ttl=-<NUM_LIT:1>):
check_not_none(key, "<STR_LIT>")<EOL>key_data = self._to_data(key)<EOL>return self._encode_invoke_on_key(map_lock_codec, key_data, invocation_timeout=MAX_SIZE, key=key_data,<EOL>thread_id=thread_id(), ttl=to_millis(ttl),<EOL>reference_id=self.reference_id_generator.get_and_increment())<EOL>
Acquires the lock for the specified key infinitely or for the specified lease time if provided.

If the lock is not available, the current thread becomes disabled for thread scheduling purposes and lies
dormant until the lock has been acquired.

You get a lock whether the value is present in the map or not. Other threads (possibly on other systems) would
block on their invoke of lock() until the non-existent key is unlocked. If the lock holder introduces the key to
the map, the put() operation is not blocked. If a thread not holding a lock on the non-existent key tries to
introduce the key while a lock exists on the non-existent key, the put() operation blocks until it is unlocked.

Scope of the lock is this map only. Acquired lock is only for the key in this map.

Locks are re-entrant; so, if the key is locked N times, it should be unlocked N times before another thread can
acquire it.

**Warning: This method uses __hash__ and __eq__ methods of binary form of the key, not the actual implementations
of __hash__ and __eq__ defined in key's class.**

:param key: (object), the key to lock.
:param ttl: (int), time in seconds to wait before releasing the lock (optional).