diff --git a/.classpath b/.classpath
index fceb480..3e0fb27 100644
--- a/.classpath
+++ b/.classpath
@@ -1,6 +1,7 @@
-
+
+
diff --git a/.gitignore b/.gitignore
index 6dae747..26aa6af 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
+bin/
+
# Windows image file caches
Thumbs.db
ehthumbs.db
diff --git a/README.md b/README.md
index f8f6d1b..83940b7 100644
--- a/README.md
+++ b/README.md
@@ -7,3 +7,5 @@ Provided examples of new features added to Java 8.
Added examples for Java 8 features like Lambda Expressions.
+Creating new branch from Master for this project.
+
diff --git a/src/com/java8/concurrency/cache/Cache.java b/src/com/java8/concurrency/cache/Cache.java
new file mode 100644
index 0000000..5eb8462
--- /dev/null
+++ b/src/com/java8/concurrency/cache/Cache.java
@@ -0,0 +1,14 @@
+package com.java8.concurrency.cache;
+
+import com.java8.concurrency.model.Key;
+import com.java8.concurrency.model.UserVO;
+
+public interface Cache {
+
+ public void put(Key key, UserVO value);
+
+ public UserVO get(Key key);
+
+ public int getSize();
+
+}
diff --git a/src/com/java8/concurrency/cache/CacheImpl.java b/src/com/java8/concurrency/cache/CacheImpl.java
new file mode 100644
index 0000000..1037986
--- /dev/null
+++ b/src/com/java8/concurrency/cache/CacheImpl.java
@@ -0,0 +1,53 @@
+package com.java8.concurrency.cache;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+import com.java8.concurrency.model.Key;
+import com.java8.concurrency.model.UserVO;
+
+public class CacheImpl implements Cache {
+
+ private static CacheImpl instance;
+
+ private ConcurrentHashMap cacheMap;
+
+ static {
+ synchronized (CacheImpl.class) {
+ if(CacheImpl.instance == null) {
+ CacheImpl.instance = new CacheImpl();
+ }
+ }
+ }
+
+ private CacheImpl() {
+ cacheMap = new ConcurrentHashMap<>();
+ }
+
+ public static Cache getCache() {
+ return instance;
+ }
+
+ @Override
+ public void put(Key key, UserVO value) {
+
+ UserVO userVO = cacheMap.get(key);
+
+ if(userVO == null) {
+ userVO = cacheMap.putIfAbsent(key, userVO);
+ if(userVO == null)
+ userVO = value;
+ }
+
+ }
+
+ @Override
+ public UserVO get(Key key) {
+ return cacheMap.get(key);
+ }
+
+ @Override
+ public int getSize() {
+ return cacheMap.keySet().size();
+ }
+
+}
diff --git a/src/com/java8/concurrency/cache/CacheTest.java b/src/com/java8/concurrency/cache/CacheTest.java
new file mode 100644
index 0000000..4ded883
--- /dev/null
+++ b/src/com/java8/concurrency/cache/CacheTest.java
@@ -0,0 +1,86 @@
+package com.java8.concurrency.cache;
+
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.java8.concurrency.model.Key;
+import com.java8.concurrency.model.UserVO;
+
+public class CacheTest {
+
+ private static Cache cache1, cache2;
+
+ @BeforeClass
+ public static void setUp() throws Exception {
+
+ cache1 = CacheImpl.getCache();
+ System.out.println("Cache1 - " + cache1);
+ System.out.println("Cache1 - hashcode: " + cache1.hashCode());
+ cache2 = CacheImpl.getCache();
+ System.out.println("Cache2 - " + cache2);
+ System.out.println("Cache2 - hashcode: " + cache2.hashCode());
+ }
+
+ @Test
+ public void testUnique() {
+ assertTrue(cache1 == cache2);
+ }
+
+ @Test
+ public void testThreadSafety(){
+
+ int threadCount = 5;
+
+ ExecutorService service = Executors.newFixedThreadPool(threadCount);
+
+ List> futures = new ArrayList<>();
+
+ for(int count = 0; count < threadCount ; count++) {
+
+ final int i = count;
+
+ Callable callable = new Callable() {
+
+ @Override
+ public Void call() throws Exception {
+ Key key1 = new Key("Ware", (20+i));
+ CacheImpl.getCache().put(key1, new UserVO("ware", "800 West Trade St.", "Consultant", 8));
+ Key key2 = new Key("Nitin", 24);
+ CacheImpl.getCache().put(key2, new UserVO("Nitin", "7416 Marchand Lane, Charlotte", "Consultant", (7 + i)));
+ return null;
+ }
+ };
+ Future submit = service.submit(callable);
+ futures.add(submit);
+ }
+
+ service.shutdown();
+
+ try {
+ TimeUnit.SECONDS.sleep(4);
+ } catch (InterruptedException e1) {
+ e1.printStackTrace();
+ }
+
+ /*for(Future future : futures) {
+ try {
+ future.get();
+ } catch (InterruptedException | ExecutionException e) {
+ e.printStackTrace();
+ }
+ }*/
+ assertEquals(6, CacheImpl.getCache().getSize());
+ }
+
+}
diff --git a/src/com/java8/concurrency/examples/CallableDemo.java b/src/com/java8/concurrency/examples/CallableDemo.java
new file mode 100644
index 0000000..aca20f9
--- /dev/null
+++ b/src/com/java8/concurrency/examples/CallableDemo.java
@@ -0,0 +1,39 @@
+package com.java8.concurrency.examples;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+public class CallableDemo {
+
+ public static void main(String[] args) {
+
+ try {
+
+ Callable task = () -> {
+ TimeUnit.SECONDS.sleep(1);
+ return 123;
+ };
+
+ ExecutorService service = Executors.newFixedThreadPool(1);
+
+ Future future = service.submit(task);
+
+ System.out.println("future done? " + future.isDone());
+
+ Integer result = future.get();
+
+ System.out.println("future done? " + future.isDone());
+ System.out.println("result: " + result);
+
+ service.shutdown();
+
+ } catch (InterruptedException | ExecutionException e) {
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/src/com/java8/concurrency/examples/ExecutorServiceDemo.java b/src/com/java8/concurrency/examples/ExecutorServiceDemo.java
new file mode 100644
index 0000000..0b16a55
--- /dev/null
+++ b/src/com/java8/concurrency/examples/ExecutorServiceDemo.java
@@ -0,0 +1,24 @@
+package com.java8.concurrency.examples;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+public class ExecutorServiceDemo {
+
+ public static void main(String[] args) {
+
+ try {
+ ExecutorService service = Executors.newSingleThreadExecutor();
+ service.submit(() -> {
+ String name = Thread.currentThread().getName();
+ System.out.println("Hello - " + name);
+ });
+ service.shutdown();
+ service.awaitTermination(5, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/src/com/java8/concurrency/examples/RunnableDemo.java b/src/com/java8/concurrency/examples/RunnableDemo.java
new file mode 100644
index 0000000..2e64881
--- /dev/null
+++ b/src/com/java8/concurrency/examples/RunnableDemo.java
@@ -0,0 +1,29 @@
+package com.java8.concurrency.examples;
+
+import java.util.concurrent.TimeUnit;
+
+public class RunnableDemo {
+
+ public static void main(String[] args) {
+
+ Runnable task = () -> {
+ try {
+ String threadName = Thread.currentThread().getName();
+ System.out.println("Foo " + threadName);
+ TimeUnit.SECONDS.sleep(1);
+ System.out.println("Bar " + threadName);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ };
+
+ task.run();
+
+ Thread thread = new Thread(task);
+ thread.start();
+
+ System.out.println("Done!!!");
+
+ }
+
+}
diff --git a/src/com/java8/concurrency/model/Key.java b/src/com/java8/concurrency/model/Key.java
new file mode 100644
index 0000000..a9b9f8e
--- /dev/null
+++ b/src/com/java8/concurrency/model/Key.java
@@ -0,0 +1,54 @@
+package com.java8.concurrency.model;
+
+import java.util.Objects;
+
+public final class Key {
+
+ private String name;
+
+ private int age;
+
+ public Key(String name, int age) {
+ this.name = name;
+ this.age = age;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+
+ if(obj == null) return false;
+
+ if(getClass() != obj.getClass()) return false;
+
+ final Key key = (Key) obj;
+
+ if(!Objects.equals(this.name, key.name)) return false;
+
+ if(!Objects.equals(this.age, key.age)) return false;
+
+ return true;
+
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(this.name, this.age);
+ }
+
+}
diff --git a/src/com/java8/concurrency/model/UserVO.java b/src/com/java8/concurrency/model/UserVO.java
new file mode 100644
index 0000000..05530fa
--- /dev/null
+++ b/src/com/java8/concurrency/model/UserVO.java
@@ -0,0 +1,51 @@
+package com.java8.concurrency.model;
+
+public class UserVO {
+
+ private String name;
+
+ private String address;
+
+ private String occupation;
+
+ private int expYrs;
+
+ public UserVO(String name, String address, String occupation, int expYrs) {
+ this.name = name;
+ this.address = address;
+ this.occupation = occupation;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getAddress() {
+ return address;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+
+ public String getOccupation() {
+ return occupation;
+ }
+
+ public void setOccupation(String occupation) {
+ this.occupation = occupation;
+ }
+
+ public int getExpYrs() {
+ return expYrs;
+ }
+
+ public void setExpYrs(int expYrs) {
+ this.expYrs = expYrs;
+ }
+
+}
diff --git a/src/com/java8/examples/StreamExample.java b/src/com/java8/examples/StreamExample.java
index 8183743..aa2e7b8 100644
--- a/src/com/java8/examples/StreamExample.java
+++ b/src/com/java8/examples/StreamExample.java
@@ -15,6 +15,7 @@ public static void main(String[] args) {
boolean isPresent = false;
List strCollection = new ArrayList<>();
+ strCollection.add("riaan");
strCollection.add("nitin");
strCollection.add("pratik");
strCollection.add("subin");