diff --git a/README.md b/README.md
index 7df1539..bc64d54 100644
--- a/README.md
+++ b/README.md
@@ -171,7 +171,11 @@ After [successfully included the library in your project](#2-installation), you
+ Setup the `NotifyingThreads`, and include them inside the `ThreadsPooling`.
+ Call `ThreadsPooling.start()` method for start executing the threads.
-You can see some examples at the [test folder](https://github.com/Javinator9889/ThreadingTools/tree/master/threadingtools/src/test/java), in which all those process and lambda usage are specified.
+You can see some examples at the [examples folder](https://github.com/Javinator9889/ThreadingTools/tree/master/examples),
+in which all those process and lambda usage are specified.
+
+If you need more information, [read the docs](https://javinator9889.github.io/ThreadingTools/) in
+ which you will find **every method detailed and explained**.
## 4. Contributing
diff --git a/examples/1-CreatingAPooling.md b/examples/1-CreatingAPooling.md
new file mode 100644
index 0000000..2e07681
--- /dev/null
+++ b/examples/1-CreatingAPooling.md
@@ -0,0 +1,65 @@
+# Examples
+
+## 1. Creating a pooling
+
+
+One of the common usages of **this library** (*[ThreadingTools](https://github.com/Javinator9889/ThreadingTools)*)
+ is to concurrently run **a predefined number of threads**, but specifying upper limits (for not
+ running all threads at the same time).
+
+ *ThreadingTools* provides a utility for generating a **pool** of threads that will run
+ concurrently, `ThreadsPooling`, accessed via `Builder` inner class.
+
+For creating a new instance, we will use:
+
+ + `builder()`, for obtaining the builder object.
+ + `build()`, for creating the `ThreadsPooling` class.
+
+All other methods are detailed and specified at the
+[official documentation](https://javinator9889.github.io/ThreadingTools/com/github/javinator9889/threading/pools/ThreadsPooling.Builder.html#method.detail)
+which explains everything you need to know for creating a new `ThreadsPooling` class.
+
+----------------
+
+```java
+import com.github.javinator9889.threading.pools.ThreadsPooling;
+
+
+public class ExampleClass {
+ private ThreadsPooling mPooling;
+
+ public ExampleClass() {
+ // Constructor that initializes the ThreadsPooling object
+
+ // In this example, we will use the number of processor
+ // for defining the concurrent jobs running.
+ // Also, the maximum jobs running will be twice number
+ // of processor.
+ int numberOfProcessors = getNumberOfProcessors();
+ int maxProcessRunning = numberOfProcessor * 2;
+ // We are going to execute at most 20 threads
+ int queueCapacity = 20;
+ // We want threads to terminate when they become idle
+ // after one second
+ long keepAliveTime = 1L;
+
+ // We are leaving ThreadFactory and
+ // RejectedExecutionHandler to their defaults
+ mPooling = ThreadsPooling.builder()
+ .withConcurrentThreadsRunning(numberOfProcessors)
+ .withMaximumPoolSize(maxProcessRunning)
+ .withQueueCapacity(queueCapacity)
+ .withKeepAliveInSeconds(keepAliveTime)
+ .build();
+
+ // Now we have the ThreadsPooling object created
+ // We could have add the threads we want to execute
+ // with the methods: "withThread()" and "withThreads"
+ }
+
+ // Method for getting the generated ThreadsPooling
+ public ThreadsPooling getPooling() {
+ return mPooling;
+ }
+}
+```
\ No newline at end of file
diff --git a/examples/2-CreatingANotifyingThread.md b/examples/2-CreatingANotifyingThread.md
new file mode 100644
index 0000000..b6f657d
--- /dev/null
+++ b/examples/2-CreatingANotifyingThread.md
@@ -0,0 +1,87 @@
+# Examples
+
+## 2. Creating a NotifyingThread
+
+As explained at *README*, there are several ways to know when a **thread** has finished its job:
+
+ + **Using** a `Future` object, in which you define *what is going to be executed* and then,
+ wait for its result (if it has one).
+ **Advantages**: you will only have the result when the `Future` is done.
+ **Disadvantages**: if there is no result, you will not know when the `Future` is done.
+
+ + **Using** a `Thread` object, and call `join()`, blocking your main thread (or *any other
+ thread where `join()` was called*) for a non-defined time.
+ **Advantages**: you do not need to use any other lib, it is a *built-in*.
+ **Disadvantages**: you dedicate a **hole process** to wait for a thread that maybe do not finish.
+
+With `NotifyingThread`, all those problems disappear, as:
+
+ + You can **get notified** of the threads *you want to get notified by*.
+ + You do not have to **actively wait** for a thread to *finish*.
+ + You can use them as `Future`, because until the result is not set, there is nothing at its
+ output.
+
+For taking advantage of all those *functionalities*, you just need to **subscribe you class**
+(that must implement `OnThreadCompletedListener`) to the correspondent `NotifyingThread`. If not,
+ it is just a simple thread 🤷
+
+------------------
+
+```java
+import com.github.javinator9889.threading.threads.notifyingthread.*;
+
+public class NotifyingThreadExampleClass implements OnThreadCompletedListener {
+ // Default constructor - we do not need anything else
+ public NotifyingThreadExampleClass() {}
+
+ public void executeAThread() {
+ // Generate a new NotifyingThread
+ // We are using a lambda expression for providing the
+ // Runnable class; it is the same as doing:
+ //
+ // new NotifyingThread(new Runnable() {
+ // @Override
+ // public void run() {
+ // System.out.println("Hi, I am a NotifyingThread");
+ // }
+ // });
+ NotifyingThread thread = new NotifyingThread(() ->
+ System.out.println("Hi, I am a NotifyingThread")
+ );
+
+ // Subscribe this class (NotifyingThreadExampleClass)
+ // for getting notified whether the thread has finished
+ // or it was interrupted by an exception
+ thread.addOnThreadCompletedListener(this);
+
+ // Setup a custom name for identification
+ thread.setName("NotifyingThreadExample");
+
+ // Start executing - this is always necessary
+ thread.start();
+ }
+
+ // Custom implementation for knowing that a thread has finished
+ // Here, we can wait until a concrete thread has finished for starting
+ // another job that requires the thread that called "onThreadCompletedListener"
+ // to finish.
+ @Override
+ public void onThreadCompletedListener(Thread thread, @Nullable Throwable exception) {
+ switch (thread.getName()) {
+ case "NotifyingThreadExample":
+ System.out.println("NotifyingThread finished!");
+ if (exception != null) {
+ System.err.println("NotifyingThread threw an exception during execution");
+ exception.printStackTrace();
+ } else {
+ System.out.println("NotifyingThread finished without errors");
+ anotherThreadThatRequiresNotifyingThreadToFinish().start();
+ }
+ break;
+ default:
+ System.err.println("Mmmmm");
+ break;
+ }
+ }
+}
+```
\ No newline at end of file
diff --git a/examples/3-UsingLambdas.md b/examples/3-UsingLambdas.md
new file mode 100644
index 0000000..f1d1e7e
--- /dev/null
+++ b/examples/3-UsingLambdas.md
@@ -0,0 +1,121 @@
+# Examples
+
+## 3. Using lambdas
+
+`Thread` does not allow us to **change its runnable** once it has been created, which is not a
+problem (is very strange to change that once a thread is created) but can be.
+
+If you have read the [documentation about NotifyingThread](https://javinator9889.github.io/ThreadingTools/com/github/javinator9889/threading/threads/notifyingthread/NotifyingThread.html),
+you have noticed that there are **four methods** for setting an executable *once the class is
+created*. Those methods are:
+
+ + `setExecutable(Runnable runnable)`
+ + `setExecutable(Consumer consumer, ArgumentParser args)`
+ + `setExecutable(Function function, ArgumentParser args, AtomicReference result)`
+ + `setExecutable(Supplier supplier, AtomicReference result)`
+
+Those methods, taking advantage of **lambda expressions**, allows you to directly **refer to a
+method** and its arguments on a single line, with the following format:
+
+ class::methodReference
+
+--------------
+
+```java
+import com.github.javinator9889.threading.threads.notifyingthread.NotifyingThread;
+import com.github.javinator9889.utils.ArgumentParser;
+
+public class LambdasExampleClass {
+ private int mFirstField;
+ private String mSecondField;
+ private ArrayList> mThirdField;
+
+ // A constructor that initializes the class fields
+ // All methods used are invented and they have no implementation
+ public LambdasExampleClass() {
+ mFirstField = getRandomValue();
+ mSecondField = getRandomString();
+ mThirdField = generateListOfMaps();
+ }
+
+ public void runnableOperation() {
+ // Operation that takes no arguments and return nothing
+ System.out.println(mFirstField + mSecondField + mThirdField.toString());
+ }
+
+ public void consumerOperation(ArgumentParser args) {
+ int valueToConsume = args.getInt("value");
+ // Do something with the value, for example, assigning
+ // "mFirstField" to the pow of that two values
+ mFirstField = Math.pow(valueToConsume, mFirstField);
+ }
+
+ public String supplierOperation() {
+ // Do something with the "mSecondField", for example,
+ // appending current thread name
+ return mSecondField + Thread.currentThread().getName();
+ }
+
+ public List