Last active
August 29, 2015 14:27
-
-
Save kundzi/7c72d478fc9aaf1a9dfd to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Here is the test lives | |
| package com.company; | |
| import com.google.common.base.Preconditions; | |
| import com.google.common.collect.Lists; | |
| import java.util.ArrayList; | |
| import java.util.function.Consumer; | |
| public class Main { | |
| static class SetterThread<T> extends Thread { | |
| final SynchProperty<T> target; | |
| final T value; | |
| final long timeout; | |
| SetterThread(SynchProperty<T> target, T value, long timeout) { | |
| this.target = target; | |
| this.value = value; | |
| this.timeout = timeout; | |
| } | |
| @Override | |
| public void run() { | |
| try { | |
| Thread.sleep(timeout); | |
| target.set(value); | |
| System.out.printf("Set to: %s <-> %s\n", value, target.get()); | |
| } catch (InterruptedException e) { | |
| e.printStackTrace(); | |
| } | |
| } | |
| static <T> SetterThread<T> create(SynchProperty<T> target, T value, long timeout) { | |
| return new SetterThread<T>(target, value, timeout); | |
| } | |
| } | |
| enum TestEnum { | |
| A, B, C, D, E | |
| } | |
| public static void main(String[] args) { | |
| for (int i = 0; i < 1000; i++) { | |
| runTest(); | |
| } | |
| } | |
| private static void runTest() { | |
| final SynchProperty<TestEnum> property = new SynchProperty<TestEnum>(); | |
| SetterThread.create(property, TestEnum.A, 100).start(); | |
| SetterThread.create(property, TestEnum.B, 150).start(); | |
| SetterThread.create(property, TestEnum.C, 200).start(); | |
| SetterThread.create(property, TestEnum.D, 250).start(); | |
| SetterThread.create(property, TestEnum.E, 300).start(); | |
| SetterThread.create(property, null, 350).start(); | |
| final ArrayList<TestEnum> valueToWait = Lists.newArrayList(TestEnum.values()); | |
| valueToWait.add(null); // last value | |
| valueToWait.stream().forEach(new Consumer<TestEnum>() { | |
| @Override | |
| public void accept(TestEnum expected) { | |
| System.out.printf("Waiting for: %s, current: %s\n", expected, property.get()); | |
| Preconditions.checkState(property.waitForValue(expected)); | |
| System.out.printf("Received value: %s, current: %s\n", expected, property.get()); | |
| } | |
| }); | |
| SetterThread.create(property, TestEnum.A, 100).start(); | |
| SetterThread.create(property, TestEnum.B, 150).start(); | |
| SetterThread.create(property, TestEnum.C, 200).start(); | |
| SetterThread.create(property, TestEnum.D, 250).start(); | |
| SetterThread.create(property, TestEnum.E, 300).start(); | |
| SetterThread.create(property, null, 350).start(); | |
| valueToWait.stream().forEach(new Consumer<TestEnum>() { | |
| @Override | |
| public void accept(TestEnum expected) { | |
| final long timeout = 400; | |
| System.out.printf("Waiting with timeout[%d] for: %s, current: %s\n", timeout, expected, property.get()); | |
| Preconditions.checkState(property.waitForValue(expected, timeout)); | |
| System.out.printf("Received value: %s, current: %s\n", expected, property.get()); | |
| } | |
| }); | |
| SetterThread.create(property, TestEnum.A, 100).start(); | |
| Preconditions.checkState(!property.waitForValue(TestEnum.A, 10)); | |
| SetterThread.create(property, TestEnum.B, 100).start(); | |
| Preconditions.checkState(!property.waitForValue(TestEnum.B, 1)); | |
| try { | |
| property.waitForValue(TestEnum.C, 0); | |
| Preconditions.checkState(false); | |
| } catch (Exception expected) { | |
| System.out.printf("Cant use not positive timeout. Bla\n"); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.company; | |
| import com.google.common.base.Preconditions; | |
| import java.util.Objects; | |
| /** | |
| * Created by 7times6 on 20/08/15. | |
| */ | |
| public class SynchProperty<T> { | |
| private final Object mutex = new Object(); | |
| private T value; | |
| public void set(T value) { | |
| synchronized (mutex) { | |
| this.value = value; | |
| mutex.notifyAll(); | |
| } | |
| } | |
| public T get() { | |
| synchronized (mutex) { | |
| return value; | |
| } | |
| } | |
| public boolean waitForValue(T expected) { | |
| synchronized (mutex) { | |
| if (Objects.equals(value, expected)) { | |
| return true; | |
| } | |
| while (value != expected) { | |
| try { | |
| mutex.wait(); | |
| } catch (InterruptedException e) { | |
| return false; | |
| } | |
| } | |
| return true; | |
| } | |
| } | |
| public boolean waitForValue(T expected, long timeout) { | |
| Preconditions.checkArgument(timeout > 0); | |
| synchronized (mutex) { | |
| final long startTime = System.currentTimeMillis(); | |
| final long endTime = startTime + timeout; | |
| while (endTime >= System.currentTimeMillis()) { | |
| if (Objects.equals(value, expected)) { | |
| return true; | |
| } | |
| final long timeToWait = endTime - System.currentTimeMillis(); | |
| try { | |
| if (timeToWait > 0) { | |
| mutex.wait(); | |
| } | |
| } catch (InterruptedException e) { | |
| return false; | |
| } | |
| } | |
| return false; | |
| } | |
| } | |
| @Override | |
| public String toString() { | |
| return "SyncProperty:" + String.valueOf(value) + "]"; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment