Skip to content

Instantly share code, notes, and snippets.

@mathieucarbou
Last active May 11, 2021 02:07
Show Gist options
  • Save mathieucarbou/9e0f2da72e8a80e04683e7e845b14978 to your computer and use it in GitHub Desktop.
Save mathieucarbou/9e0f2da72e8a80e04683e7e845b14978 to your computer and use it in GitHub Desktop.
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.LongAdder;
import java.util.stream.Stream;
import static java.lang.Thread.sleep;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static java.util.stream.Collectors.toList;
public class ButtonRace {
public static void main(String[] args) throws InterruptedException {
Button ok = new Button("OK", () -> System.out.println("TASK: OK"));
Button cancel = new Button("CANCEL", () -> System.out.println("TASK: CANCEL"));
// Button ok = new Button("OK");
// Button cancel = new Button("CANCEL");
CountDownLatch start = new CountDownLatch(1);
List<Thread> threads = Stream.of(ok, cancel).map(button -> new Thread(() -> {
try {
start.await();
while (!Thread.currentThread().isInterrupted()) {
button.click();
}
} catch (Exception ignored) {
}
})).collect(toList());
threads.forEach(Thread::start);
start.countDown();
sleep(5_000);
threads.forEach(Thread::interrupt);
for (Thread thread : threads) {
thread.join();
}
System.out.println(ok);
System.out.println(cancel);
}
public static class Button {
private final String name;
private final List<Runnable> tasks;
private final LongAdder clicks = new LongAdder();
public Button(String name) {
this.name = name;
this.tasks = emptyList();
}
public Button(String name, Runnable... runnable) {
this.name = name;
this.tasks = asList(runnable);
}
public void click() {
clicks.increment();
synchronized (tasks) {
//System.out.println("Clicking(" + this + ")");
doingSomeWork();
tasks.forEach(Runnable::run);
//System.out.println("Clicked(" + this + ")");
}
}
// [...]
@Override
public String toString() {
return name + ": " + clicks + " clicks";
}
private void doingSomeWork() {
try {
sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment