/* package whatever; // don't place package name! */
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.locks.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone {
private static final ConcurrentHashMap
<String, Semaphore
> map
= new ConcurrentHashMap
<>();
private static void callLongRunningMethod() {
System.
out.
println("Start " + Thread.
currentThread().
getName()); try {
Thread.
currentThread().
interrupt(); }
System.
out.
println("End " + Thread.
currentThread().
getName()); }
public static void test
(String hash
) { Semaphore s = map.computeIfAbsent(hash, k -> new Semaphore(1));
try {
s.acquire();
}
try {
callLongRunningMethod();
} finally {
s.release();
map.remove(hash, s);
}
}
() -> {
test("");
test("");
})
.start();
() -> {
test("");
test("");
})
.start();
// your code goes here
}
}
LyogcGFja2FnZSB3aGF0ZXZlcjsgLy8gZG9uJ3QgcGxhY2UgcGFja2FnZSBuYW1lISAqLwoKaW1wb3J0IGphdmEudXRpbC4qOwppbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuKjsKaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmxvY2tzLio7CmltcG9ydCBqYXZhLmxhbmcuKjsKaW1wb3J0IGphdmEuaW8uKjsKCi8qIE5hbWUgb2YgdGhlIGNsYXNzIGhhcyB0byBiZSAiTWFpbiIgb25seSBpZiB0aGUgY2xhc3MgaXMgcHVibGljLiAqLwpjbGFzcyBJZGVvbmUgewoKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBDb25jdXJyZW50SGFzaE1hcDxTdHJpbmcsIFNlbWFwaG9yZT4gbWFwID0gbmV3IENvbmN1cnJlbnRIYXNoTWFwPD4oKTsKCiAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBjYWxsTG9uZ1J1bm5pbmdNZXRob2QoKSB7CiAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlN0YXJ0ICIgKyBUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldE5hbWUoKSk7CiAgICB0cnkgewogICAgICBUaHJlYWQuc2xlZXAoNTAwKTsKICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKICAgICAgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5pbnRlcnJ1cHQoKTsKICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CiAgICB9CiAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkVuZCAiICsgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXROYW1lKCkpOwogIH0KCiAgcHVibGljIHN0YXRpYyB2b2lkIHRlc3QoU3RyaW5nIGhhc2gpIHsKICAgIFNlbWFwaG9yZSBzID0gbWFwLmNvbXB1dGVJZkFic2VudChoYXNoLCBrIC0+IG5ldyBTZW1hcGhvcmUoMSkpOwogICAgdHJ5IHsKICAgIAlzLmFjcXVpcmUoKTsKICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKICAgIAl0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKICAgIH0KICAgIHRyeSB7CiAgICAgICAgY2FsbExvbmdSdW5uaW5nTWV0aG9kKCk7CiAgICB9IGZpbmFsbHkgewogICAgICAgIHMucmVsZWFzZSgpOwogICAgICAgIG1hcC5yZW1vdmUoaGFzaCwgcyk7CiAgICB9Cn0KCiAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgdGhyb3dzIGphdmEubGFuZy5FeGNlcHRpb24gewogICAgbmV3IFRocmVhZCgKICAgICAgICAgICAgKCkgLT4gewogICAgICAgICAgICAgIHRlc3QoIiIpOwogICAgICAgICAgICAgIHRlc3QoIiIpOwogICAgICAgICAgICB9KQogICAgICAgIC5zdGFydCgpOwogICAgbmV3IFRocmVhZCgKICAgICAgICAgICAgKCkgLT4gewogICAgICAgICAgICAgIHRlc3QoIiIpOwogICAgICAgICAgICAgIHRlc3QoIiIpOwogICAgICAgICAgICB9KQogICAgICAgIC5zdGFydCgpOwogICAgLy8geW91ciBjb2RlIGdvZXMgaGVyZQogIH0KfQo=