/* 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 final ConcurrentHashMap
<String, Future
<?>> pending
= new ConcurrentHashMap
<>(); private final ExecutorService executor;
private final long start;
Ideone(ExecutorService executor) {
this.executor = executor;
this.
start = System.
nanoTime(); }
System.
out.
println(Thread.
currentThread().
getName() + " started at: " + ((System.
nanoTime() - start
) / 1e9
) + "s");
Future<?> future =
pending.computeIfAbsent(hash, k -> executor.submit(() -> longRunningMethod()));
try {
future.get(); // Block until LRM has finished.
System.
out.
println(Thread.
currentThread().
getName() + " completed after: " + ((System.
nanoTime() - start
) / 1e9
) + "s"); } catch (ExecutionException e) {
Thread.
currentThread().
interrupt(); } finally {
pending.values().remove(future);
}
}
void longRunningMethod() {
System.
out.
println("Start: " + Thread.
currentThread().
getName()); try {
Thread.
currentThread().
interrupt(); }
System.
out.
println("End: " + Thread.
currentThread().
getName()); }
for (Thread t
: ts
) t.
start(); }
ExecutorService executor = Executors.newCachedThreadPool();
try {
Ideone instance = new Ideone(executor);
// These threads all run concurrently, and basically finish at the same
// time.
// The LRM needs to be called again for these threads.
} finally {
executor.shutdown();
}
}
}
LyogcGFja2FnZSB3aGF0ZXZlcjsgLy8gZG9uJ3QgcGxhY2UgcGFja2FnZSBuYW1lISAqLwoKaW1wb3J0IGphdmEudXRpbC4qOwppbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuKjsKaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmxvY2tzLio7CmltcG9ydCBqYXZhLmxhbmcuKjsKaW1wb3J0IGphdmEuaW8uKjsKCi8qIE5hbWUgb2YgdGhlIGNsYXNzIGhhcyB0byBiZSAiTWFpbiIgb25seSBpZiB0aGUgY2xhc3MgaXMgcHVibGljLiAqLwpjbGFzcyBJZGVvbmUgewogIHByaXZhdGUgZmluYWwgQ29uY3VycmVudEhhc2hNYXA8U3RyaW5nLCBGdXR1cmU8Pz4+IHBlbmRpbmcgPSBuZXcgQ29uY3VycmVudEhhc2hNYXA8PigpOwogIHByaXZhdGUgZmluYWwgRXhlY3V0b3JTZXJ2aWNlIGV4ZWN1dG9yOwogIHByaXZhdGUgZmluYWwgbG9uZyBzdGFydDsKCiAgSWRlb25lKEV4ZWN1dG9yU2VydmljZSBleGVjdXRvcikgewogICAgdGhpcy5leGVjdXRvciA9IGV4ZWN1dG9yOwogICAgdGhpcy5zdGFydCA9IFN5c3RlbS5uYW5vVGltZSgpOwogIH0KCiAgdm9pZCB0ZXN0KFN0cmluZyBoYXNoKSB7CiAgCVN5c3RlbS5vdXQucHJpbnRsbihUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldE5hbWUoKSArICIgc3RhcnRlZCBhdDogIiArICgoU3lzdGVtLm5hbm9UaW1lKCkgLSBzdGFydCkgLyAxZTkpICsgInMiKTsKICAJCiAgICBGdXR1cmU8Pz4gZnV0dXJlID0KICAgICAgICBwZW5kaW5nLmNvbXB1dGVJZkFic2VudChoYXNoLCBrIC0+IGV4ZWN1dG9yLnN1Ym1pdCgoKSAtPiBsb25nUnVubmluZ01ldGhvZCgpKSk7CiAgICB0cnkgewogICAgICBmdXR1cmUuZ2V0KCk7IC8vIEJsb2NrIHVudGlsIExSTSBoYXMgZmluaXNoZWQuCiAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldE5hbWUoKSArICIgY29tcGxldGVkIGFmdGVyOiAiICsgKChTeXN0ZW0ubmFub1RpbWUoKSAtIHN0YXJ0KSAvIDFlOSkgKyAicyIpOwogICAgfSBjYXRjaCAoRXhlY3V0aW9uRXhjZXB0aW9uIGUpIHsKICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CiAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CiAgICAgIFRocmVhZC5jdXJyZW50VGhyZWFkKCkuaW50ZXJydXB0KCk7CiAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOwogICAgfSBmaW5hbGx5IHsKICAgICAgcGVuZGluZy52YWx1ZXMoKS5yZW1vdmUoZnV0dXJlKTsKICAgIH0KICB9CgogIHZvaWQgbG9uZ1J1bm5pbmdNZXRob2QoKSB7CiAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlN0YXJ0OiAiICsgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXROYW1lKCkpOwogICAgdHJ5IHsKICAgICAgVGhyZWFkLnNsZWVwKDUwMCk7CiAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CiAgICAgIFRocmVhZC5jdXJyZW50VGhyZWFkKCkuaW50ZXJydXB0KCk7CiAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOwogICAgfQogICAgU3lzdGVtLm91dC5wcmludGxuKCJFbmQ6ICIgKyBUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldE5hbWUoKSk7CiAgfQoKICBzdGF0aWMgdm9pZCBzdGFydEFuZFJ1bihUaHJlYWQuLi4gdHMpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CiAgCWZvciAoVGhyZWFkIHQgOiB0cykgdC5zdGFydCgpOwogIAlmb3IgKFRocmVhZCB0IDogdHMpIHQuam9pbigpOwogIH0KCiAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgdGhyb3dzIGphdmEubGFuZy5FeGNlcHRpb24gewogICAgRXhlY3V0b3JTZXJ2aWNlIGV4ZWN1dG9yID0gRXhlY3V0b3JzLm5ld0NhY2hlZFRocmVhZFBvb2woKTsKICAgIHRyeSB7CiAgICAgIElkZW9uZSBpbnN0YW5jZSA9IG5ldyBJZGVvbmUoZXhlY3V0b3IpOwoKICAgICAgUnVubmFibGUgciA9ICgpIC0+IGluc3RhbmNlLnRlc3QoIiIpOwoKICAgICAgLy8gVGhlc2UgdGhyZWFkcyBhbGwgcnVuIGNvbmN1cnJlbnRseSwgYW5kIGJhc2ljYWxseSBmaW5pc2ggYXQgdGhlIHNhbWUKICAgICAgLy8gdGltZS4KICAgICAgc3RhcnRBbmRSdW4obmV3IFRocmVhZChyKSwgbmV3IFRocmVhZChyKSwgbmV3IFRocmVhZChyKSk7CiAgICAgIC8vIFRoZSBMUk0gbmVlZHMgdG8gYmUgY2FsbGVkIGFnYWluIGZvciB0aGVzZSB0aHJlYWRzLgogICAgICBzdGFydEFuZFJ1bihuZXcgVGhyZWFkKHIpLCBuZXcgVGhyZWFkKHIpKTsKICAgIH0gZmluYWxseSB7CiAgICAgIGV4ZWN1dG9yLnNodXRkb3duKCk7CiAgICB9CiAgfQp9Cg==