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.Pool/pom.xml b/01.Pool/pom.xml
new file mode 100644
index 0000000..a0377c5
--- /dev/null
+++ b/01.Pool/pom.xml
@@ -0,0 +1,31 @@
+
+
+ 4.0.0
+
+ 01
+ Pool
+ 1.0-SNAPSHOT
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 1.8
+ 1.8
+
+
+
+
+
+
+ junit
+ junit
+ 4.12
+
+
+
+
+
\ No newline at end of file
diff --git a/01.Pool/src/main/java/ru/spbau/mit/alyokhina/LightExecutionException.java b/01.Pool/src/main/java/ru/spbau/mit/alyokhina/LightExecutionException.java
new file mode 100644
index 0000000..745c303
--- /dev/null
+++ b/01.Pool/src/main/java/ru/spbau/mit/alyokhina/LightExecutionException.java
@@ -0,0 +1,8 @@
+package ru.spbau.mit.alyokhina;
+
+/** if in calculating supplier of the LightFuture we caught an exception, we throw LightExecutionException */
+public class LightExecutionException extends Exception {
+ public LightExecutionException(String msg) {
+ super(msg);
+ }
+}
diff --git a/01.Pool/src/main/java/ru/spbau/mit/alyokhina/LightFuture.java b/01.Pool/src/main/java/ru/spbau/mit/alyokhina/LightFuture.java
new file mode 100644
index 0000000..6f53c17
--- /dev/null
+++ b/01.Pool/src/main/java/ru/spbau/mit/alyokhina/LightFuture.java
@@ -0,0 +1,22 @@
+package ru.spbau.mit.alyokhina;
+
+import java.util.function.Function;
+
+/** Interface for tasks accepted for execution */
+public interface LightFuture {
+ /** if task was calculated then return true, else - false */
+ boolean isReady();
+
+ /**
+ * Calculate supplier
+ * @return the value obtained
+ * @throws LightExecutionException if in calculating supplier of the LightFuture we caught an exception
+ */
+ T get() throws LightExecutionException;
+
+ /**
+ * Accepts an object of type Function that can be applied to the result of this task T and returns a new task T accepted for execution
+ * @return new task type of T
+ */
+ LightFuture thenApply(Function function);
+}
diff --git a/01.Pool/src/main/java/ru/spbau/mit/alyokhina/Pool.java b/01.Pool/src/main/java/ru/spbau/mit/alyokhina/Pool.java
new file mode 100644
index 0000000..fe008bb
--- /dev/null
+++ b/01.Pool/src/main/java/ru/spbau/mit/alyokhina/Pool.java
@@ -0,0 +1,165 @@
+package ru.spbau.mit.alyokhina;
+
+import java.util.ArrayDeque;
+import java.util.Queue;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+/**
+ * Task pool with a fixed number of threads
+ */
+public class Pool {
+ /**
+ * All created threads
+ */
+ private Thread threads[];
+
+ /**
+ * Accepted tasks
+ */
+ private final Queue tasks = new ArrayDeque<>();
+
+ /**
+ * Constructor
+ *
+ * @param n number of threads
+ */
+ public Pool(int n) {
+ threads = new Thread[n];
+ for (int i = 0; i < threads.length; i++) {
+ threads[i] = new Thread(() -> {
+ LightFutureImpl cur;
+ try {
+ while (!Thread.interrupted()) {
+ synchronized (tasks) {
+ while (tasks.isEmpty()) {
+ tasks.wait();
+ }
+ cur = tasks.poll();
+ }
+ cur.calculate();
+ }
+ }
+ catch (InterruptedException ignored) {
+ }
+ }
+ );
+ threads[i].start();
+ }
+ }
+
+ /**
+ * Shutting down all threads
+ */
+ public void shutdown() {
+ for (Thread thread : threads) {
+ thread.interrupt();
+ }
+ }
+
+ /** Return all threads */
+ public Thread[] getThreads() {
+ return threads;
+ }
+
+ /**
+ * Add new task and notify threads that are waiting for a new task
+ */
+ public LightFuture add(Supplier supplier) {
+ LightFutureImpl newTask = new LightFutureImpl(supplier);
+ synchronized (tasks) {
+ tasks.add(newTask);
+ tasks.notify();
+ }
+ return newTask;
+ }
+
+ /**
+ * Class for task implements LightFuture
+ */
+ private class LightFutureImpl implements LightFuture {
+ /**
+ * value was calculated
+ */
+ private boolean ready = false;
+
+ /**
+ * Error in calculating the supplier
+ */
+ private LightExecutionException exception;
+ private Supplier supplier;
+ /**
+ * the value that was received when calculating the supplier
+ */
+ private T ans = null;
+
+ /**
+ * Constructor
+ *
+ * @param supplier for calculating value
+ */
+ public LightFutureImpl(Supplier supplier) {
+ this.supplier = supplier;
+ }
+
+ /**
+ * Value was calculated
+ *
+ * @return true if value was calculated, false - else
+ */
+ @Override
+ public boolean isReady() {
+ return ready;
+ }
+
+ /**
+ * Calculate task
+ */
+ private synchronized void calculate() {
+ if (!ready) {
+ try {
+ ans = supplier.get();
+ } catch (Exception e) {
+ exception = new LightExecutionException(e.getMessage());
+ }
+ ready = true;
+ notifyAll();
+ }
+ }
+
+ /**
+ * expect calculation if not calculated yet
+ *
+ * @return result which was calculated
+ * @throws LightExecutionException if in calculating supplier of the LightFuture we caught an exception
+ */
+ public synchronized T get() throws LightExecutionException {
+ while (!ready) {
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ throw new LightExecutionException("Interrupted");
+ }
+ }
+ if (exception != null) {
+ throw exception;
+ }
+ return ans;
+ }
+
+ /**
+ * Accepts an object of type Function that can be applied to the result of this task T and returns a new task E accepted for execution
+ *
+ * @return new task type of E
+ */
+ public LightFuture thenApply(Function function) {
+ return add(() -> {
+ try {
+ return function.apply(get());
+ } catch (LightExecutionException e) {
+ throw new RuntimeException(e.getMessage(), e.getCause());
+ }
+ });
+ }
+ }
+}
\ No newline at end of file
diff --git a/01.Pool/src/test/java/ru/spbau/mit/alyokhina/PoolTest.java b/01.Pool/src/test/java/ru/spbau/mit/alyokhina/PoolTest.java
new file mode 100644
index 0000000..9a4884a
--- /dev/null
+++ b/01.Pool/src/test/java/ru/spbau/mit/alyokhina/PoolTest.java
@@ -0,0 +1,100 @@
+package ru.spbau.mit.alyokhina;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class PoolTest {
+ @Test
+ public void testConstructor() {
+ Pool threadPools = new Pool<>(5);
+ for (int i = 0; i < 5; i++) {
+ final int j = i;
+ threadPools.add(() -> j);
+ }
+ }
+
+ /**
+ * @throws LightExecutionException if in calculating supplier of the LightFuture we caught an exception
+ */
+ @Test
+ public void testWithOneThread() throws LightExecutionException {
+ Pool threadPools = new Pool<>(1);
+ LightFuture task = threadPools.add(() -> 1408);
+ assertEquals((Integer) 1408, task.get());
+ }
+
+
+ /**
+ * @throws LightExecutionException if in calculating supplier of the LightFuture we caught an exception
+ */
+ @Test
+ public void testAdd() throws LightExecutionException {
+ Pool threadPools = new Pool<>(15);
+ LightFuture tasks[] = new LightFuture[20];
+ for (int i = 0; i < 20; i++) {
+ final int j = i;
+ tasks[i] = threadPools.add(() -> j);
+ }
+
+ for (int i = 0; i < 20; i++) {
+ assertEquals((Integer) i, tasks[i].get());
+ }
+
+ }
+
+ @Test(expected = LightExecutionException.class)
+ public void testLightExecutionException() throws LightExecutionException {
+ Pool threadPools = new Pool<>(15);
+ LightFuture tasks[] = new LightFuture[5];
+ for (int i = 0; i < 5; i++) {
+ tasks[i] = threadPools.add(() -> {
+ throw new RuntimeException("");
+ });
+ }
+ for (int i = 0; i < 5; i++) {
+ tasks[i].get();
+ }
+ }
+
+ @Test
+ public void testShutdown() {
+ Pool threadPools = new Pool<>(15);
+ LightFuture tasks[] = new LightFuture[20];
+ for (int i = 0; i < 20; i++) {
+ final int j = i;
+ tasks[i] = threadPools.add(() -> j);
+ }
+ threadPools.shutdown();
+ try {
+ Thread.sleep(3000);
+ } catch (InterruptedException e) {
+ System.out.println(e.getMessage());
+ }
+ Thread[] threads = threadPools.getThreads();
+ for (int i = 0; i < threads.length; i++) {
+ assertEquals(false, threads[i].isAlive());
+ }
+ }
+
+ /**
+ * @throws LightExecutionException if in calculating supplier of the LightFuture we caught an exception
+ */
+ @Test
+ public void tesThenApplyOnce() throws LightExecutionException {
+ Pool threadPools = new Pool<>(15);
+ LightFuture task = threadPools.add(() -> 5).thenApply(x -> x * 2);
+ assertEquals((Integer) 10, task.get());
+ }
+
+ /**
+ * @throws LightExecutionException if in calculating supplier of the LightFuture we caught an exception
+ */
+ @Test
+ public void tesThenApply() throws LightExecutionException {
+ Pool threadPools = new Pool<>(15);
+ LightFuture task = threadPools.add(() -> 5).thenApply(x -> x * 2).thenApply(x -> x + 4);
+ assertEquals((Integer) 14, task.get());
+ }
+
+}
\ 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
+