From 3ed3bc1fa52b7c1ce9a5684ce08ac03073e7668b Mon Sep 17 00:00:00 2001 From: gwildor28 Date: Mon, 7 Mar 2016 19:40:50 +0000 Subject: [PATCH 01/14] Added mutex and semaphore modules to demonstrate locks Added two modules to demonstrate locks. Mutex demonstrates a simple mutual exclusion lock. Semaphore demonstrates a semaphore for controlling access to a pool of resources. The main class of both programs is App.java. --- mutex/pom.xml | 35 ++++++ .../src/main/java/com/iluwatar/mutex/App.java | 42 +++++++ .../src/main/java/com/iluwatar/mutex/Jar.java | 58 ++++++++++ .../main/java/com/iluwatar/mutex/Lock.java | 34 ++++++ .../main/java/com/iluwatar/mutex/Mutex.java | 46 ++++++++ .../main/java/com/iluwatar/mutex/Thief.java | 51 +++++++++ pom.xml | 2 + semaphore/pom.xml | 35 ++++++ .../main/java/com/iluwatar/semaphore/App.java | 43 ++++++++ .../java/com/iluwatar/semaphore/Customer.java | 63 +++++++++++ .../java/com/iluwatar/semaphore/Fruit.java | 60 ++++++++++ .../com/iluwatar/semaphore/FruitBowl.java | 78 +++++++++++++ .../com/iluwatar/semaphore/FruitShop.java | 103 ++++++++++++++++++ .../java/com/iluwatar/semaphore/Lock.java | 34 ++++++ .../com/iluwatar/semaphore/Semaphore.java | 51 +++++++++ 15 files changed, 735 insertions(+) create mode 100644 mutex/pom.xml create mode 100644 mutex/src/main/java/com/iluwatar/mutex/App.java create mode 100644 mutex/src/main/java/com/iluwatar/mutex/Jar.java create mode 100644 mutex/src/main/java/com/iluwatar/mutex/Lock.java create mode 100644 mutex/src/main/java/com/iluwatar/mutex/Mutex.java create mode 100644 mutex/src/main/java/com/iluwatar/mutex/Thief.java create mode 100644 semaphore/pom.xml create mode 100644 semaphore/src/main/java/com/iluwatar/semaphore/App.java create mode 100644 semaphore/src/main/java/com/iluwatar/semaphore/Customer.java create mode 100644 semaphore/src/main/java/com/iluwatar/semaphore/Fruit.java create mode 100644 semaphore/src/main/java/com/iluwatar/semaphore/FruitBowl.java create mode 100644 semaphore/src/main/java/com/iluwatar/semaphore/FruitShop.java create mode 100644 semaphore/src/main/java/com/iluwatar/semaphore/Lock.java create mode 100644 semaphore/src/main/java/com/iluwatar/semaphore/Semaphore.java diff --git a/mutex/pom.xml b/mutex/pom.xml new file mode 100644 index 000000000..5b7058083 --- /dev/null +++ b/mutex/pom.xml @@ -0,0 +1,35 @@ + + + + 4.0.0 + + com.iluwatar + java-design-patterns + 1.11.0-SNAPSHOT + + mutex + diff --git a/mutex/src/main/java/com/iluwatar/mutex/App.java b/mutex/src/main/java/com/iluwatar/mutex/App.java new file mode 100644 index 000000000..e2d10763f --- /dev/null +++ b/mutex/src/main/java/com/iluwatar/mutex/App.java @@ -0,0 +1,42 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.mutex; + +/** + * App. + */ +public class App { + + /** + * main method + */ + public static void main(String[] args) { + Mutex mutex = new Mutex(); + Jar jar = new Jar(mutex); + Thief peter = new Thief("Peter", jar); + Thief john = new Thief("John", jar); + peter.start(); + john.start(); + } + +} diff --git a/mutex/src/main/java/com/iluwatar/mutex/Jar.java b/mutex/src/main/java/com/iluwatar/mutex/Jar.java new file mode 100644 index 000000000..6cbe009d8 --- /dev/null +++ b/mutex/src/main/java/com/iluwatar/mutex/Jar.java @@ -0,0 +1,58 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.mutex; + +/** + * Jar. + */ +public class Jar { + + private Lock lock; + + private int beans = 1000; + + public Jar(Lock lock) { + this.lock = lock; + } + + /** + * takeBean method + */ + public boolean takeBean(Thief thief) { + boolean success = false; + try { + lock.acquire(); + success = beans > 0; + if (success) { + beans = beans - 1; + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + lock.release(); + } + + return success; + } + +} diff --git a/mutex/src/main/java/com/iluwatar/mutex/Lock.java b/mutex/src/main/java/com/iluwatar/mutex/Lock.java new file mode 100644 index 000000000..b748f3761 --- /dev/null +++ b/mutex/src/main/java/com/iluwatar/mutex/Lock.java @@ -0,0 +1,34 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.mutex; + +/** + * Lock. + */ +public interface Lock { + + void acquire() throws InterruptedException; + + void release(); + +} diff --git a/mutex/src/main/java/com/iluwatar/mutex/Mutex.java b/mutex/src/main/java/com/iluwatar/mutex/Mutex.java new file mode 100644 index 000000000..a8cf6a919 --- /dev/null +++ b/mutex/src/main/java/com/iluwatar/mutex/Mutex.java @@ -0,0 +1,46 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.mutex; + +/** + * Mutex. + */ +public class Mutex implements Lock { + private Object owner = null; + + @Override + public synchronized void acquire() throws InterruptedException { + while (owner != null) { + wait(); + } + + owner = Thread.currentThread(); + } + + @Override + public synchronized void release() { + owner = null; + notify(); + } + +} diff --git a/mutex/src/main/java/com/iluwatar/mutex/Thief.java b/mutex/src/main/java/com/iluwatar/mutex/Thief.java new file mode 100644 index 000000000..8fbc75f92 --- /dev/null +++ b/mutex/src/main/java/com/iluwatar/mutex/Thief.java @@ -0,0 +1,51 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.mutex; + +/** + * Thief. + */ +public class Thief extends Thread { + + private String name; + + private Jar jar; + + public Thief(String name, Jar jar) { + this.name = name; + this.jar = jar; + } + + @Override + public void run() { + int beans = 0; + + while (jar.takeBean(this)) { + beans = beans + 1; + System.out.println(name + " took a bean."); + } + + System.out.println(name + " took " + beans + " beans."); + } + +} diff --git a/pom.xml b/pom.xml index 555844660..fa0fe771c 100644 --- a/pom.xml +++ b/pom.xml @@ -123,6 +123,8 @@ feature-toggle value-object monad + mutex + semaphore diff --git a/semaphore/pom.xml b/semaphore/pom.xml new file mode 100644 index 000000000..66a961c3f --- /dev/null +++ b/semaphore/pom.xml @@ -0,0 +1,35 @@ + + + + 4.0.0 + + com.iluwatar + java-design-patterns + 1.11.0-SNAPSHOT + + semaphore + diff --git a/semaphore/src/main/java/com/iluwatar/semaphore/App.java b/semaphore/src/main/java/com/iluwatar/semaphore/App.java new file mode 100644 index 000000000..4dd5a764a --- /dev/null +++ b/semaphore/src/main/java/com/iluwatar/semaphore/App.java @@ -0,0 +1,43 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.semaphore; + +/** + * App. + */ +public class App { + + /** + * main method + */ + public static void main(String[] args) { + FruitShop shop = new FruitShop(); + new Customer("Peter", shop).start(); + new Customer("Paul", shop).start(); + new Customer("Mary", shop).start(); + new Customer("John", shop).start(); + new Customer("Ringo", shop).start(); + new Customer("George", shop).start(); + } + +} diff --git a/semaphore/src/main/java/com/iluwatar/semaphore/Customer.java b/semaphore/src/main/java/com/iluwatar/semaphore/Customer.java new file mode 100644 index 000000000..a3fc65ac3 --- /dev/null +++ b/semaphore/src/main/java/com/iluwatar/semaphore/Customer.java @@ -0,0 +1,63 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.semaphore; + +/** + * Customer. + */ +public class Customer extends Thread { + + private String name; + private FruitShop fruitShop; + private FruitBowl fruitBowl; + + /** + * Customer constructor + */ + public Customer(String name, FruitShop fruitShop) { + this.name = name; + this.fruitShop = fruitShop; + this.fruitBowl = new FruitBowl(); + } + + /** + * run method + */ + public void run() { + + while (fruitShop.countFruit() > 0) { + FruitBowl bowl = fruitShop.takeBowl(); + Fruit fruit; + + if (bowl != null && (fruit = bowl.take()) != null) { + System.out.println(name + " took an " + fruit); + fruitBowl.put(fruit); + fruitShop.returnBowl(bowl); + } + } + + System.out.println(name + " took " + fruitBowl); + + } + +} diff --git a/semaphore/src/main/java/com/iluwatar/semaphore/Fruit.java b/semaphore/src/main/java/com/iluwatar/semaphore/Fruit.java new file mode 100644 index 000000000..ecf8d1d29 --- /dev/null +++ b/semaphore/src/main/java/com/iluwatar/semaphore/Fruit.java @@ -0,0 +1,60 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.semaphore; + +/** + * Fruit. + */ +public class Fruit { + + public static enum FruitType { + ORANGE, APPLE, LEMON + } + + private FruitType type; + + public Fruit(FruitType type) { + this.type = type; + } + + public FruitType getType() { + return type; + } + + /** + * toString method + */ + public String toString() { + switch (type) { + case ORANGE: + return "Orange"; + case APPLE: + return "Apple"; + case LEMON: + return "Lemon"; + default: + return ""; + } + } + +} diff --git a/semaphore/src/main/java/com/iluwatar/semaphore/FruitBowl.java b/semaphore/src/main/java/com/iluwatar/semaphore/FruitBowl.java new file mode 100644 index 000000000..7760b8e3a --- /dev/null +++ b/semaphore/src/main/java/com/iluwatar/semaphore/FruitBowl.java @@ -0,0 +1,78 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.semaphore; + +import java.util.ArrayList; + +/** + * FruitBowl. + */ +public class FruitBowl { + + private ArrayList fruit = new ArrayList<>(); + + public int countFruit() { + return fruit.size(); + } + + public void put(Fruit f) { + fruit.add(f); + } + + /** + * take method + */ + public Fruit take() { + if (fruit.isEmpty()) { + return null; + } else { + return fruit.remove(0); + } + } + + /** + * toString method + */ + public String toString() { + int apples = 0; + int oranges = 0; + int lemons = 0; + + for (Fruit f : fruit) { + switch (f.getType()) { + case APPLE: + apples++; + break; + case ORANGE: + oranges++; + break; + case LEMON: + lemons++; + break; + default: + } + } + + return apples + " Apples, " + oranges + " Oranges, and " + lemons + " Lemons"; + } +} diff --git a/semaphore/src/main/java/com/iluwatar/semaphore/FruitShop.java b/semaphore/src/main/java/com/iluwatar/semaphore/FruitShop.java new file mode 100644 index 000000000..fff764bad --- /dev/null +++ b/semaphore/src/main/java/com/iluwatar/semaphore/FruitShop.java @@ -0,0 +1,103 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.semaphore; + +/** + * FruitShop. + */ +public class FruitShop { + + private FruitBowl[] bowls = { + new FruitBowl(), + new FruitBowl(), + new FruitBowl() + }; + + private boolean[] available = { + true, + true, + true + }; + + private Semaphore semaphore; + + /** + * FruitShop constructor + */ + public FruitShop() { + for (int i = 0; i < 100; i++) { + bowls[0].put(new Fruit(Fruit.FruitType.APPLE)); + bowls[1].put(new Fruit(Fruit.FruitType.ORANGE)); + bowls[2].put(new Fruit(Fruit.FruitType.LEMON)); + } + + semaphore = new Semaphore(3); + } + + public synchronized int countFruit() { + return bowls[0].countFruit() + bowls[1].countFruit() + bowls[2].countFruit(); + } + + /** + * takeBowl method + */ + public synchronized FruitBowl takeBowl() { + + FruitBowl bowl = null; + + try { + semaphore.acquire(); + + if (available[0]) { + bowl = bowls[0]; + available[0] = false; + } else if (available[1]) { + bowl = bowls[1]; + available[1] = false; + } else if (available[2]) { + bowl = bowls[2]; + available[2] = false; + } + + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + semaphore.release(); + } + return bowl; + } + + /** + * returnBowl method + */ + public synchronized void returnBowl(FruitBowl bowl) { + if (bowl == bowls[0]) { + available[0] = true; + } else if (bowl == bowls[1]) { + available[1] = true; + } else if (bowl == bowls[2]) { + available [2] = true; + } + } + +} diff --git a/semaphore/src/main/java/com/iluwatar/semaphore/Lock.java b/semaphore/src/main/java/com/iluwatar/semaphore/Lock.java new file mode 100644 index 000000000..99b8f85b5 --- /dev/null +++ b/semaphore/src/main/java/com/iluwatar/semaphore/Lock.java @@ -0,0 +1,34 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.semaphore; + +/** + * Lock. + */ +public interface Lock { + + void acquire() throws InterruptedException; + + void release(); + +} diff --git a/semaphore/src/main/java/com/iluwatar/semaphore/Semaphore.java b/semaphore/src/main/java/com/iluwatar/semaphore/Semaphore.java new file mode 100644 index 000000000..5873df2b5 --- /dev/null +++ b/semaphore/src/main/java/com/iluwatar/semaphore/Semaphore.java @@ -0,0 +1,51 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.semaphore; + +/** + * Semaphore. + */ +public class Semaphore implements Lock { + + private int counter; + + public Semaphore(int counter) { + this.counter = counter; + } + + /** + * acquire method + */ + public synchronized void acquire() throws InterruptedException { + while (counter == 0) { + wait(); + } + counter = counter - 1; + } + + public synchronized void release() { + counter = counter + 1; + notify(); + } + +} From 6e4b2699398231f47b0bcf75b22336d4d470fd27 Mon Sep 17 00:00:00 2001 From: gwildor28 Date: Thu, 24 Mar 2016 18:13:37 +0000 Subject: [PATCH 02/14] Update according to review comments #397 - Added descriptions - Added junit tests - Added javadoc - Added index.md - Added class diagrams --- mutex/etc/mutex.png | Bin 0 -> 12737 bytes mutex/index.md | 30 ++++++++++++++++ mutex/pom.xml | 9 ++++- .../src/main/java/com/iluwatar/mutex/App.java | 10 +++++- .../src/main/java/com/iluwatar/mutex/Jar.java | 14 ++++++-- .../main/java/com/iluwatar/mutex/Lock.java | 2 +- .../main/java/com/iluwatar/mutex/Mutex.java | 16 +++++++-- .../main/java/com/iluwatar/mutex/Thief.java | 19 +++++++--- .../test/java/com/iluwatar/mutex/AppTest.java | 34 ++++++++++++++++++ semaphore/etc/semaphore.png | Bin 0 -> 30089 bytes semaphore/index.md | 33 +++++++++++++++++ semaphore/pom.xml | 9 ++++- .../main/java/com/iluwatar/semaphore/App.java | 9 ++++- .../java/com/iluwatar/semaphore/Customer.java | 25 +++++++++---- .../java/com/iluwatar/semaphore/Fruit.java | 2 +- .../com/iluwatar/semaphore/FruitBowl.java | 16 +++++++-- .../com/iluwatar/semaphore/FruitShop.java | 31 ++++++++++++---- .../java/com/iluwatar/semaphore/Lock.java | 2 +- .../com/iluwatar/semaphore/Semaphore.java | 12 +++++-- .../java/com/iluwatar/semaphore/AppTest.java | 34 ++++++++++++++++++ 20 files changed, 273 insertions(+), 34 deletions(-) create mode 100644 mutex/etc/mutex.png create mode 100644 mutex/index.md create mode 100644 mutex/src/test/java/com/iluwatar/mutex/AppTest.java create mode 100644 semaphore/etc/semaphore.png create mode 100644 semaphore/index.md create mode 100644 semaphore/src/test/java/com/iluwatar/semaphore/AppTest.java diff --git a/mutex/etc/mutex.png b/mutex/etc/mutex.png new file mode 100644 index 0000000000000000000000000000000000000000..3b7c966f87dffab72c65a77c2578c801086f7d9e GIT binary patch literal 12737 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 VGkgbka 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 RF7OUbSwT&{Qq~OqKL9K>lx6?` literal 0 HcmV?d00001 diff --git a/mutex/index.md b/mutex/index.md new file mode 100644 index 000000000..24edad7eb --- /dev/null +++ b/mutex/index.md @@ -0,0 +1,30 @@ +--- +layout: pattern +title: Mutex +folder: mutex +permalink: /patterns/mutex/ +categories: Lock +tags: + - Java + - Difficulty-Beginner +--- + +## Also known as +Mutual Exclusion Lock +Binary Semaphore + +## Intent +Create a lock which only allows a single thread to access a resource at any one instant. + +![alt text](./etc/mutex.png "Mutex") + +## Applicability +Use a Mutex when + +* you need to prevent two threads accessing a critical section at the same time +* concurrent access to a resource could lead to a race condition + +## Credits + +* [Lock (computer science)] (http://en.wikipedia.org/wiki/Lock_(computer_science)) +* [Semaphores] (http://tutorials.jenkov.com/java-concurrency/semaphores.html) diff --git a/mutex/pom.xml b/mutex/pom.xml index 5b7058083..07c2d793c 100644 --- a/mutex/pom.xml +++ b/mutex/pom.xml @@ -2,7 +2,7 @@ @@ -50,6 +45,7 @@ 19.0 1.15.1 1.10.19 + 4.12.1 abstract-factory @@ -123,8 +119,7 @@ feature-toggle value-object monad - mutex - semaphore + mute-idiom @@ -197,6 +192,12 @@ ${systemrules.version} test + + de.bechte.junit + junit-hierarchicalcontextrunner + ${hierarchical-junit-runner-version} + test + @@ -396,4 +397,4 @@ - + \ No newline at end of file From ca8be7c43e3bc5a1590c5352137dcb2e203855b5 Mon Sep 17 00:00:00 2001 From: gwildor28 Date: Wed, 13 Apr 2016 19:26:31 +0100 Subject: [PATCH 06/14] pom update --- pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pom.xml b/pom.xml index 98b79de08..9d66f5f9b 100644 --- a/pom.xml +++ b/pom.xml @@ -120,6 +120,8 @@ value-object monad mute-idiom + mutex + semaphore From 685d093cff803609c25d35e58bf663c55262c2fa Mon Sep 17 00:00:00 2001 From: gwildor28 Date: Thu, 14 Apr 2016 17:33:52 +0100 Subject: [PATCH 07/14] added relative paths to pom in mutex/semaphore --- mutex/pom.xml | 1 + semaphore/pom.xml | 1 + 2 files changed, 2 insertions(+) diff --git a/mutex/pom.xml b/mutex/pom.xml index 07c2d793c..6e418c1d1 100644 --- a/mutex/pom.xml +++ b/mutex/pom.xml @@ -30,6 +30,7 @@ com.iluwatar java-design-patterns 1.11.0-SNAPSHOT + ../pom.xml mutex diff --git a/semaphore/pom.xml b/semaphore/pom.xml index 14b551a1a..2d0bfb907 100644 --- a/semaphore/pom.xml +++ b/semaphore/pom.xml @@ -30,6 +30,7 @@ com.iluwatar java-design-patterns 1.11.0-SNAPSHOT + ../pom.xml semaphore From e821abdb1bc6e7a4238318bf89afb9cdb7810d95 Mon Sep 17 00:00:00 2001 From: gwildor28 Date: Thu, 14 Apr 2016 17:44:18 +0100 Subject: [PATCH 08/14] updated version to fix pom --- mutex/pom.xml | 3 +-- semaphore/pom.xml | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/mutex/pom.xml b/mutex/pom.xml index 6e418c1d1..c9e0e83b7 100644 --- a/mutex/pom.xml +++ b/mutex/pom.xml @@ -29,8 +29,7 @@ com.iluwatar java-design-patterns - 1.11.0-SNAPSHOT - ../pom.xml + 1.12.0-SNAPSHOT mutex diff --git a/semaphore/pom.xml b/semaphore/pom.xml index 2d0bfb907..a2dc143a1 100644 --- a/semaphore/pom.xml +++ b/semaphore/pom.xml @@ -29,8 +29,7 @@ com.iluwatar java-design-patterns - 1.11.0-SNAPSHOT - ../pom.xml + 1.12.0-SNAPSHOT semaphore From 439e286f00e9c671cf940ccc3834f4342853766b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Fri, 15 Apr 2016 08:13:51 +0300 Subject: [PATCH 09/14] Fix minor display error --- business-delegate/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/business-delegate/README.md b/business-delegate/README.md index 7d6df3346..b5d37235c 100644 --- a/business-delegate/README.md +++ b/business-delegate/README.md @@ -25,4 +25,5 @@ Use the Business Delegate pattern when * you want to encapsulate service lookups and service calls ##Credits + * [J2EE Design Patterns](http://www.amazon.com/J2EE-Design-Patterns-William-Crawford/dp/0596004273/ref=sr_1_2) From 8e69ebce9f8d03e4e785e1cd60bd063b4dc56e7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Fri, 15 Apr 2016 08:21:29 +0300 Subject: [PATCH 10/14] Fix display error --- callback/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/callback/README.md b/callback/README.md index be73dc78f..a408fd5e0 100644 --- a/callback/README.md +++ b/callback/README.md @@ -25,4 +25,4 @@ Use the Callback pattern when ## Real world examples -* [CyclicBarrier] (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CyclicBarrier.html#CyclicBarrier%28int,%20java.lang.Runnable%29) constructor can accept callback that will be triggered every time when barrier is tripped. +* [CyclicBarrier](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CyclicBarrier.html#CyclicBarrier%28int,%20java.lang.Runnable%29) constructor can accept callback that will be triggered every time when barrier is tripped. From cf0570a5ed271d1d561667867f2fa568a8218cb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Fri, 15 Apr 2016 08:38:08 +0300 Subject: [PATCH 11/14] Fix display error --- lazy-loading/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/lazy-loading/README.md b/lazy-loading/README.md index d2c3db615..ca18c8f65 100644 --- a/lazy-loading/README.md +++ b/lazy-loading/README.md @@ -29,4 +29,5 @@ Use the Lazy Loading idiom when * JPA annotations @OneToOne, @OneToMany, @ManyToOne, @ManyToMany and fetch = FetchType.LAZY ##Credits + * [J2EE Design Patterns](http://www.amazon.com/J2EE-Design-Patterns-William-Crawford/dp/0596004273/ref=sr_1_2) From 6f89315aa946dcc80ee414722979c956fb59c77d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Fri, 15 Apr 2016 08:41:15 +0300 Subject: [PATCH 12/14] Fix minor display error on web site --- publish-subscribe/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/publish-subscribe/README.md b/publish-subscribe/README.md index a19aa1031..703960a93 100644 --- a/publish-subscribe/README.md +++ b/publish-subscribe/README.md @@ -18,9 +18,8 @@ Broadcast messages from sender to all the interested receivers. ## Applicability Use the Publish Subscribe Channel pattern when -* two or more applications need to communicate using a messaging system for broadcasts. -======= * two or more applications need to communicate using a messaging system for broadcasts. ##Credits + * [J2EE Design Patterns](http://www.amazon.com/J2EE-Design-Patterns-William-Crawford/dp/0596004273/ref=sr_1_2) From 886ad7e8f00b6dfc279253a12709e45f24be23c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 16 Apr 2016 08:52:16 +0300 Subject: [PATCH 13/14] Fix some markdown errors --- business-delegate/README.md | 2 +- lazy-loading/README.md | 2 +- publish-subscribe/README.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/business-delegate/README.md b/business-delegate/README.md index b5d37235c..e6e249122 100644 --- a/business-delegate/README.md +++ b/business-delegate/README.md @@ -24,6 +24,6 @@ Use the Business Delegate pattern when * you want to orchestrate calls to multiple business services * you want to encapsulate service lookups and service calls -##Credits +## Credits * [J2EE Design Patterns](http://www.amazon.com/J2EE-Design-Patterns-William-Crawford/dp/0596004273/ref=sr_1_2) diff --git a/lazy-loading/README.md b/lazy-loading/README.md index ca18c8f65..d40061293 100644 --- a/lazy-loading/README.md +++ b/lazy-loading/README.md @@ -28,6 +28,6 @@ Use the Lazy Loading idiom when * JPA annotations @OneToOne, @OneToMany, @ManyToOne, @ManyToMany and fetch = FetchType.LAZY -##Credits +## Credits * [J2EE Design Patterns](http://www.amazon.com/J2EE-Design-Patterns-William-Crawford/dp/0596004273/ref=sr_1_2) diff --git a/publish-subscribe/README.md b/publish-subscribe/README.md index 703960a93..6a5b2dfa8 100644 --- a/publish-subscribe/README.md +++ b/publish-subscribe/README.md @@ -20,6 +20,6 @@ Use the Publish Subscribe Channel pattern when * two or more applications need to communicate using a messaging system for broadcasts. -##Credits +## Credits * [J2EE Design Patterns](http://www.amazon.com/J2EE-Design-Patterns-William-Crawford/dp/0596004273/ref=sr_1_2) From a2843297d872df89c2d25a96bf12eb13a3852a28 Mon Sep 17 00:00:00 2001 From: gwildor28 Date: Sun, 17 Apr 2016 14:46:52 +0100 Subject: [PATCH 14/14] JUnit tests --- .../src/main/java/com/iluwatar/mutex/App.java | 2 +- .../src/main/java/com/iluwatar/mutex/Jar.java | 7 ++- .../main/java/com/iluwatar/mutex/Mutex.java | 13 ++++- .../main/java/com/iluwatar/mutex/Thief.java | 2 +- .../test/java/com/iluwatar/mutex/JarTest.java | 43 ++++++++++++++ .../java/com/iluwatar/mutex/MutexTest.java | 47 ++++++++++++++++ .../com/iluwatar/semaphore/Semaphore.java | 26 +++++++-- .../com/iluwatar/semaphore/FruitBowlTest.java | 51 +++++++++++++++++ .../com/iluwatar/semaphore/SemaphoreTest.java | 56 +++++++++++++++++++ 9 files changed, 236 insertions(+), 11 deletions(-) create mode 100644 mutex/src/test/java/com/iluwatar/mutex/JarTest.java create mode 100644 mutex/src/test/java/com/iluwatar/mutex/MutexTest.java create mode 100644 semaphore/src/test/java/com/iluwatar/semaphore/FruitBowlTest.java create mode 100644 semaphore/src/test/java/com/iluwatar/semaphore/SemaphoreTest.java diff --git a/mutex/src/main/java/com/iluwatar/mutex/App.java b/mutex/src/main/java/com/iluwatar/mutex/App.java index 559453500..f6494bd5c 100644 --- a/mutex/src/main/java/com/iluwatar/mutex/App.java +++ b/mutex/src/main/java/com/iluwatar/mutex/App.java @@ -40,7 +40,7 @@ public class App { */ public static void main(String[] args) { Mutex mutex = new Mutex(); - Jar jar = new Jar(mutex); + Jar jar = new Jar(1000, mutex); Thief peter = new Thief("Peter", jar); Thief john = new Thief("John", jar); peter.start(); diff --git a/mutex/src/main/java/com/iluwatar/mutex/Jar.java b/mutex/src/main/java/com/iluwatar/mutex/Jar.java index e049b7a75..4fe0a4637 100644 --- a/mutex/src/main/java/com/iluwatar/mutex/Jar.java +++ b/mutex/src/main/java/com/iluwatar/mutex/Jar.java @@ -37,16 +37,17 @@ public class Jar { /** * The resource within the jar. */ - private int beans = 1000; + private int beans; - public Jar(Lock lock) { + public Jar(int beans, Lock lock) { + this.beans = beans; this.lock = lock; } /** * Method for a thief to take a bean. */ - public boolean takeBean(Thief thief) { + public boolean takeBean() { boolean success = false; try { lock.acquire(); diff --git a/mutex/src/main/java/com/iluwatar/mutex/Mutex.java b/mutex/src/main/java/com/iluwatar/mutex/Mutex.java index e15deaf48..8e08534cd 100644 --- a/mutex/src/main/java/com/iluwatar/mutex/Mutex.java +++ b/mutex/src/main/java/com/iluwatar/mutex/Mutex.java @@ -32,6 +32,13 @@ public class Mutex implements Lock { */ private Object owner; + /** + * Returns the current owner of the Mutex, or null if available + */ + public Object getOwner() { + return owner; + } + /** * Method called by a thread to acquire the lock. If the lock has already * been acquired this will wait until the lock has been released to @@ -51,8 +58,10 @@ public class Mutex implements Lock { */ @Override public synchronized void release() { - owner = null; - notify(); + if (Thread.currentThread() == owner) { + owner = null; + notify(); + } } } diff --git a/mutex/src/main/java/com/iluwatar/mutex/Thief.java b/mutex/src/main/java/com/iluwatar/mutex/Thief.java index 58ce019e0..d2225876c 100644 --- a/mutex/src/main/java/com/iluwatar/mutex/Thief.java +++ b/mutex/src/main/java/com/iluwatar/mutex/Thief.java @@ -51,7 +51,7 @@ public class Thief extends Thread { public void run() { int beans = 0; - while (jar.takeBean(this)) { + while (jar.takeBean()) { beans = beans + 1; System.out.println(name + " took a bean."); } diff --git a/mutex/src/test/java/com/iluwatar/mutex/JarTest.java b/mutex/src/test/java/com/iluwatar/mutex/JarTest.java new file mode 100644 index 000000000..97101466a --- /dev/null +++ b/mutex/src/test/java/com/iluwatar/mutex/JarTest.java @@ -0,0 +1,43 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.mutex; + +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * Test case for taking beans from a Jar + */ +public class JarTest { + + @Test + public void testTakeBeans() { + Mutex mutex = new Mutex(); + Jar jar = new Jar(10, mutex); + for (int i = 0; i < 10; i++) { + assertTrue(jar.takeBean()); + } + assertFalse(jar.takeBean()); + } + +} \ No newline at end of file diff --git a/mutex/src/test/java/com/iluwatar/mutex/MutexTest.java b/mutex/src/test/java/com/iluwatar/mutex/MutexTest.java new file mode 100644 index 000000000..8b3e82cb4 --- /dev/null +++ b/mutex/src/test/java/com/iluwatar/mutex/MutexTest.java @@ -0,0 +1,47 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.mutex; + +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * Test case for acquiring and releasing a Mutex + */ +public class MutexTest { + + @Test + public void acquireReleaseTest() { + Mutex mutex = new Mutex(); + assertNull(mutex.getOwner()); + try { + mutex.acquire(); + assertEquals(mutex.getOwner(), Thread.currentThread()); + } catch (InterruptedException e) { + fail(e.toString()); + } + mutex.release(); + assertNull(mutex.getOwner()); + } + +} \ No newline at end of file diff --git a/semaphore/src/main/java/com/iluwatar/semaphore/Semaphore.java b/semaphore/src/main/java/com/iluwatar/semaphore/Semaphore.java index 79f3b4465..2e4a54c7c 100644 --- a/semaphore/src/main/java/com/iluwatar/semaphore/Semaphore.java +++ b/semaphore/src/main/java/com/iluwatar/semaphore/Semaphore.java @@ -27,13 +27,29 @@ package com.iluwatar.semaphore; */ public class Semaphore implements Lock { + private final int licenses; /** * The number of concurrent resource accesses which are allowed. */ private int counter; - public Semaphore(int counter) { - this.counter = counter; + public Semaphore(int licenses) { + this.licenses = licenses; + this.counter = licenses; + } + + /** + * Returns the number of licenses managed by the Semaphore + */ + public int getNumLicenses() { + return licenses; + } + + /** + * Returns the number of available licenses + */ + public int getAvailableLicenses() { + return counter; } /** @@ -52,8 +68,10 @@ public class Semaphore implements Lock { * Method called by a thread to release the lock. */ public synchronized void release() { - counter = counter + 1; - notify(); + if (counter < licenses) { + counter = counter + 1; + notify(); + } } } diff --git a/semaphore/src/test/java/com/iluwatar/semaphore/FruitBowlTest.java b/semaphore/src/test/java/com/iluwatar/semaphore/FruitBowlTest.java new file mode 100644 index 000000000..be31f77ab --- /dev/null +++ b/semaphore/src/test/java/com/iluwatar/semaphore/FruitBowlTest.java @@ -0,0 +1,51 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.semaphore; + +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * Test taking from and putting Fruit into a FruitBowl + */ +public class FruitBowlTest { + + @Test + public void fruitBowlTest() { + FruitBowl fbowl = new FruitBowl(); + + assertEquals(fbowl.countFruit(), 0); + + for (int i = 1; i <= 10; i++) { + fbowl.put(new Fruit(Fruit.FruitType.LEMON)); + assertEquals(fbowl.countFruit(), i); + } + + for (int i = 9; i >= 0; i--) { + assertNotNull(fbowl.take()); + assertEquals(fbowl.countFruit(), i); + } + + assertNull(fbowl.take()); + } +} diff --git a/semaphore/src/test/java/com/iluwatar/semaphore/SemaphoreTest.java b/semaphore/src/test/java/com/iluwatar/semaphore/SemaphoreTest.java new file mode 100644 index 000000000..14587a485 --- /dev/null +++ b/semaphore/src/test/java/com/iluwatar/semaphore/SemaphoreTest.java @@ -0,0 +1,56 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.semaphore; + +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * Test case for acquiring and releasing a Semaphore + */ +public class SemaphoreTest { + + @Test + public void acquireReleaseTest() { + Semaphore sphore = new Semaphore(3); + + assertEquals(sphore.getAvailableLicenses(), 3); + + for (int i = 2; i >= 0; i--) { + try { + sphore.acquire(); + assertEquals(sphore.getAvailableLicenses(), i); + } catch (InterruptedException e) { + fail(e.toString()); + } + } + + for (int i = 1; i <= 3; i++) { + sphore.release(); + assertEquals(sphore.getAvailableLicenses(), i); + } + + sphore.release(); + assertEquals(sphore.getAvailableLicenses(), 3); + } +}