diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..6b8dde0 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,7 @@ +language: java +jdk: + - oraclejdk8 +os: + - linux +script: + - chmod +x buildscript.sh && ./buildscript.sh diff --git a/01.Lazy/pom.xml b/01.Lazy/pom.xml new file mode 100644 index 0000000..1d1621b --- /dev/null +++ b/01.Lazy/pom.xml @@ -0,0 +1,36 @@ + + + 4.0.0 + + 01 + Lazy + 1.0-SNAPSHOT + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + + + junit + junit + 4.12 + + + org.jetbrains + annotations + 15.0 + + + + + \ No newline at end of file diff --git a/01.Lazy/src/main/java/ru/spbau/mit/alyokhina/Lazy.java b/01.Lazy/src/main/java/ru/spbau/mit/alyokhina/Lazy.java new file mode 100644 index 0000000..c8c4ac1 --- /dev/null +++ b/01.Lazy/src/main/java/ru/spbau/mit/alyokhina/Lazy.java @@ -0,0 +1,8 @@ +package ru.spbau.mit.alyokhina; +/** + * Lazy computing interface + * @param type of returned object + */ +public interface Lazy { + T get(); +} diff --git a/01.Lazy/src/main/java/ru/spbau/mit/alyokhina/LazyFactory.java b/01.Lazy/src/main/java/ru/spbau/mit/alyokhina/LazyFactory.java new file mode 100644 index 0000000..b47b6aa --- /dev/null +++ b/01.Lazy/src/main/java/ru/spbau/mit/alyokhina/LazyFactory.java @@ -0,0 +1,102 @@ +package ru.spbau.mit.alyokhina; + +import org.jetbrains.annotations.NotNull; + +import java.util.function.Supplier; + +/** + * Class for create object of Lazy + * There is a single-threaded and multithreaded version of the creation + * + * @param type of Lazy object + */ +public class LazyFactory { + /** + * Create Lazy object for single thread + * + * @param supplier the Lazy object is created on the basis of calculations (represented by the supplier) + * @param type of Lazy object + * @return Lazy object + */ + @NotNull + public static Lazy createLazySingleThreadMode(Supplier supplier) { + return new LazySingleThreadMode<>(supplier); + } + + /** + * Create Lazy object for many threads + * + * @param supplier the Lazy object is created on the basis of calculations (represented by the supplier) + * @param type of Lazy object + * @return Lazy object + */ + @NotNull + public static Lazy createLazyMultiThreadedMode(Supplier supplier) { + return new LazyMultiThreadMode<>(supplier); + } + + + /** + * class implementing interface Lazy for one thread + * + * @param type of Lazy object + */ + private static class LazySingleThreadMode implements Lazy { + /** The Lazy object is created on the basis of calculations (represented by the supplier) */ + private Supplier supplier; + + /** Value that came after calling the supplier (null - if there was no call) */ + private T ans; + + /** Constructor */ + private LazySingleThreadMode(Supplier supplier) { + this.supplier = supplier; + } + + /** + * If the value has not yet been calculated, then calculate + * + * @return the value that was received + */ + @Override + public T get() { + if (ans == null) { + ans = supplier.get(); + } + return ans; + } + } + + /** + * class implementing interface Lazy for many threads + * + * @param type of Lazy object + */ + private static class LazyMultiThreadMode implements Lazy { + /** The Lazy object is created on the basis of calculations (represented by the supplier) */ + private volatile Supplier supplier; + + /** Value that came after calling the supplier (null - if there was no call) */ + private T ans; + + /** Constructor */ + private LazyMultiThreadMode(Supplier supplier) { + this.supplier = supplier; + } + + /** + * If the value has not yet been calculated, then calculate + * + * @return the value that was received + */ + @Override + public T get() { + synchronized (this) { + if (ans == null) { + ans = supplier.get(); + } + } + return ans; + } + } +} diff --git a/01.Lazy/src/test/java/ru/spbau/mit/alyokhina/LazyFactoryTest.java b/01.Lazy/src/test/java/ru/spbau/mit/alyokhina/LazyFactoryTest.java new file mode 100644 index 0000000..86f1f1c --- /dev/null +++ b/01.Lazy/src/test/java/ru/spbau/mit/alyokhina/LazyFactoryTest.java @@ -0,0 +1,79 @@ +package ru.spbau.mit.alyokhina; + +import org.junit.Test; +import java.util.function.Supplier; +import static org.junit.Assert.*; + +public class LazyFactoryTest { + @Test + public void testCreateLazySingleThreadMode() { + Lazy test = LazyFactory.createLazySingleThreadMode(() -> 5); + assertEquals((Integer) 5, test.get()); + assertEquals((Integer) 5, test.get()); + } + + @Test + public void testCreateLazySingleThreadModeIfSupplierGetNull() { + Lazy test = LazyFactory.createLazySingleThreadMode(() -> null); + assertEquals(null, test.get()); + assertEquals(null, test.get()); + } + + @Test + public void testCreateLazySingleThreadModeIfSupplierChangeValue() { + Lazy test = LazyFactory.createLazySingleThreadMode(new Supplier() { + private boolean flag = false; + + @Override + public Integer get() { + Integer ans = flag ? 5 : 6; + flag = true; + return ans; + } + }); + assertEquals((Integer) 6, test.get()); + assertEquals((Integer) 6, test.get()); + } + + @Test + public void testCreateLazyMultiThreadedModeForOneThread() { + Lazy test = LazyFactory.createLazyMultiThreadedMode(() -> 5); + assertEquals((Integer) 5, test.get()); + assertEquals((Integer) 5, test.get()); + } + + @Test + public void testCreateLazyMultiThreadedModeForThreads() { + Lazy test = LazyFactory.createLazyMultiThreadedMode(() -> 5); + Thread[] threads = new Thread[1000]; + for (int i = 0; i < 1000; i++) { + threads[i] = new Thread(() -> assertEquals((Integer) 5, test.get())); + } + for (Thread thread : threads) { + thread.run(); + } + } + + @Test + public void testCreateLazyMultiThreadedModeForThreadsIfSupplierChange() throws Exception { + Lazy test = LazyFactory.createLazyMultiThreadedMode(new Supplier() { + private boolean flag = false; + + @Override + public Integer get() { + Integer ans = flag ? 5 : 6; + flag = true; + return ans; + } + }); + Thread[] threads = new Thread[1000]; + for (int i = 0; i < 1000; i++) { + + threads[i] = new Thread(() -> assertEquals((Integer) 6, test.get())); + } + for (Thread thread : threads) { + thread.run(); + } + } + +} \ No newline at end of file diff --git a/buildscript.sh b/buildscript.sh new file mode 100755 index 0000000..1cc07e7 --- /dev/null +++ b/buildscript.sh @@ -0,0 +1,9 @@ +#!/bin/bash +files=$(find . -maxdepth 1 -type d | grep "./0.*") +for file in $files +do + cd $file + mvn test -B + cd ../ +done +