### Question:
RedisCache extends AbstractRemoteCache { public Lock acquireLock(String lockName) { RLock lock = getClient().getLock(lockName); lock.lock(); return lock; } RedisCache(); byte[] get(String key); void set(String key, byte[] value); void set(String key, byte[] value, int expireIn); void delete(String key); Lock acquireLock(String lockName); @Override CheckResult checkConnection();  }### Answer:
@Test public void testLock() throws InterruptedException { String LOCK_NAME = "test-lock"; int WAIT = 20; List<String> list = Collections.synchronizedList(new ArrayList<>()); Callable<Object> task1 = () -> { Lock lock = cache.acquireLock(LOCK_NAME); Thread.sleep(WAIT); list.add("a1"); Thread.sleep(WAIT); list.add("b1"); Thread.sleep(WAIT); list.add("c1"); lock.unlock(); return null; }; Callable<Object> task2 = () -> { Lock lock = cache.acquireLock(LOCK_NAME); Thread.sleep(WAIT); list.add("a2"); Thread.sleep(WAIT); list.add("b2"); Thread.sleep(WAIT); list.add("c2"); lock.unlock(); return null; }; List<Callable<Object>> tasks = new ArrayList<>(); tasks.add(task1); tasks.add(task2); ExecutorService executorService = Executors.newFixedThreadPool(2); executorService.invokeAll(tasks); String result = String.join(",", list); assertTrue(result.equals("a1,b1,c1,a2,b2,c2") || result.equals("a2,b2,c2,a1,b1,c1")); }