Merge pull request #397 from gwildor28/master
Lock Pattern #71: Added mutex and semaphore modules to demonstrate locks
This commit is contained in:
		
							
								
								
									
										30
									
								
								mutex/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								mutex/README.md
									
									
									
									
									
										Normal file
									
								
							@@ -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.
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
## 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)
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								mutex/etc/mutex.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								mutex/etc/mutex.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 12 KiB  | 
							
								
								
									
										42
									
								
								mutex/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								mutex/pom.xml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<!--
 | 
			
		||||
 | 
			
		||||
    The MIT License
 | 
			
		||||
    Copyright (c) 2014 Ilkka Sepp<70>l<EFBFBD>
 | 
			
		||||
 | 
			
		||||
    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.
 | 
			
		||||
 | 
			
		||||
-->
 | 
			
		||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
 | 
			
		||||
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 | 
			
		||||
  <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
  <parent>
 | 
			
		||||
    <groupId>com.iluwatar</groupId>
 | 
			
		||||
    <artifactId>java-design-patterns</artifactId>
 | 
			
		||||
    <version>1.12.0-SNAPSHOT</version>
 | 
			
		||||
  </parent>
 | 
			
		||||
  <artifactId>mutex</artifactId>
 | 
			
		||||
  <dependencies>
 | 
			
		||||
    <dependency>
 | 
			
		||||
      <groupId>junit</groupId>
 | 
			
		||||
      <artifactId>junit</artifactId>
 | 
			
		||||
      <scope>test</scope>
 | 
			
		||||
    </dependency> 
 | 
			
		||||
  </dependencies>
 | 
			
		||||
</project>
 | 
			
		||||
							
								
								
									
										50
									
								
								mutex/src/main/java/com/iluwatar/mutex/App.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								mutex/src/main/java/com/iluwatar/mutex/App.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,50 @@
 | 
			
		||||
/**
 | 
			
		||||
 * 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;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A Mutex prevents multiple threads from accessing a resource simultaneously.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * In this example we have two thieves who are taking beans from a jar.
 | 
			
		||||
 * Only one thief can take a bean at a time. This is ensured by a Mutex lock
 | 
			
		||||
 * which must be acquired in order to access the jar. Each thief attempts to
 | 
			
		||||
 * acquire the lock, take a bean and then release the lock. If the lock has 
 | 
			
		||||
 * already been acquired, the thief will be prevented from continuing (blocked)
 | 
			
		||||
 * until the lock has been released. The thieves stop taking beans once there
 | 
			
		||||
 * are no beans left to take.
 | 
			
		||||
 */
 | 
			
		||||
public class App {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * main method
 | 
			
		||||
   */
 | 
			
		||||
  public static void main(String[] args) {
 | 
			
		||||
    Mutex mutex = new Mutex();
 | 
			
		||||
    Jar jar = new Jar(1000, mutex);
 | 
			
		||||
    Thief peter = new Thief("Peter", jar);
 | 
			
		||||
    Thief john = new Thief("John", jar);
 | 
			
		||||
    peter.start();
 | 
			
		||||
    john.start();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										67
									
								
								mutex/src/main/java/com/iluwatar/mutex/Jar.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								mutex/src/main/java/com/iluwatar/mutex/Jar.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,67 @@
 | 
			
		||||
/**
 | 
			
		||||
 * 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;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A Jar has a resource of beans which can only be accessed by a single Thief
 | 
			
		||||
 * (thread) at any one time. A Mutex lock is used to prevent more than one Thief
 | 
			
		||||
 * taking a bean simultaneously. 
 | 
			
		||||
 */
 | 
			
		||||
public class Jar {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The lock which must be acquired to access the beans resource.
 | 
			
		||||
   */
 | 
			
		||||
  private final Lock lock;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The resource within the jar.
 | 
			
		||||
   */
 | 
			
		||||
  private int beans;
 | 
			
		||||
 | 
			
		||||
  public Jar(int beans, Lock lock) {
 | 
			
		||||
    this.beans = beans;
 | 
			
		||||
    this.lock = lock;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Method for a thief to take a bean.
 | 
			
		||||
   */
 | 
			
		||||
  public boolean takeBean() {
 | 
			
		||||
    boolean success = false;
 | 
			
		||||
    try {
 | 
			
		||||
      lock.acquire();
 | 
			
		||||
      success = beans > 0;
 | 
			
		||||
      if (success) {
 | 
			
		||||
        beans = beans - 1;
 | 
			
		||||
      }
 | 
			
		||||
    } catch (Exception e) {
 | 
			
		||||
      e.printStackTrace();
 | 
			
		||||
    } finally {
 | 
			
		||||
      lock.release();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return success;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										34
									
								
								mutex/src/main/java/com/iluwatar/mutex/Lock.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								mutex/src/main/java/com/iluwatar/mutex/Lock.java
									
									
									
									
									
										Normal file
									
								
							@@ -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 is an interface for a lock which can be acquired and released.
 | 
			
		||||
 */
 | 
			
		||||
public interface Lock {
 | 
			
		||||
 | 
			
		||||
  void acquire() throws InterruptedException;
 | 
			
		||||
 | 
			
		||||
  void release();
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										67
									
								
								mutex/src/main/java/com/iluwatar/mutex/Mutex.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								mutex/src/main/java/com/iluwatar/mutex/Mutex.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,67 @@
 | 
			
		||||
/**
 | 
			
		||||
 * 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 is an implementation of a mutual exclusion lock.
 | 
			
		||||
 */
 | 
			
		||||
public class Mutex implements Lock {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The current owner of the 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 
 | 
			
		||||
   * re-attempt the acquire.
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  public synchronized void acquire() throws InterruptedException {
 | 
			
		||||
    while (owner != null) {
 | 
			
		||||
      wait();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    owner = Thread.currentThread();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Method called by a thread to release the lock.
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  public synchronized void release() {
 | 
			
		||||
    if (Thread.currentThread() == owner) {
 | 
			
		||||
      owner = null;
 | 
			
		||||
      notify();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										62
									
								
								mutex/src/main/java/com/iluwatar/mutex/Thief.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								mutex/src/main/java/com/iluwatar/mutex/Thief.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
/**
 | 
			
		||||
 * 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 is a class which continually tries to acquire a jar and take a bean
 | 
			
		||||
 * from it. When the jar is empty the thief stops.
 | 
			
		||||
 */
 | 
			
		||||
public class Thief extends Thread {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The name of the thief. 
 | 
			
		||||
   */
 | 
			
		||||
  private final String name;
 | 
			
		||||
  
 | 
			
		||||
  /**
 | 
			
		||||
   * The jar
 | 
			
		||||
   */
 | 
			
		||||
  private final Jar jar;
 | 
			
		||||
 | 
			
		||||
  public Thief(String name, Jar jar) {
 | 
			
		||||
    this.name = name;
 | 
			
		||||
    this.jar = jar;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * In the run method the thief repeatedly tries to take a bean until none
 | 
			
		||||
   * are left.
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  public void run() {
 | 
			
		||||
    int beans = 0;
 | 
			
		||||
 | 
			
		||||
    while (jar.takeBean()) {
 | 
			
		||||
      beans = beans + 1;
 | 
			
		||||
      System.out.println(name + " took a bean.");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    System.out.println(name + " took " + beans + " beans.");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										34
									
								
								mutex/src/test/java/com/iluwatar/mutex/AppTest.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								mutex/src/test/java/com/iluwatar/mutex/AppTest.java
									
									
									
									
									
										Normal file
									
								
							@@ -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;
 | 
			
		||||
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
 | 
			
		||||
public class AppTest{
 | 
			
		||||
  @Test
 | 
			
		||||
  public void test() throws IOException {
 | 
			
		||||
    String[] args = {};
 | 
			
		||||
    App.main(args);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										43
									
								
								mutex/src/test/java/com/iluwatar/mutex/JarTest.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								mutex/src/test/java/com/iluwatar/mutex/JarTest.java
									
									
									
									
									
										Normal file
									
								
							@@ -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());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										47
									
								
								mutex/src/test/java/com/iluwatar/mutex/MutexTest.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								mutex/src/test/java/com/iluwatar/mutex/MutexTest.java
									
									
									
									
									
										Normal file
									
								
							@@ -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());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										9
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								pom.xml
									
									
									
									
									
								
							@@ -1,19 +1,15 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<!--
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
@@ -21,7 +17,6 @@
 | 
			
		||||
    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.
 | 
			
		||||
 | 
			
		||||
-->
 | 
			
		||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
 | 
			
		||||
		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 | 
			
		||||
@@ -125,6 +120,8 @@
 | 
			
		||||
		<module>value-object</module>
 | 
			
		||||
		<module>monad</module>
 | 
			
		||||
		<module>mute-idiom</module>
 | 
			
		||||
		<module>mutex</module>
 | 
			
		||||
		<module>semaphore</module>
 | 
			
		||||
	</modules>
 | 
			
		||||
 | 
			
		||||
	<dependencyManagement>
 | 
			
		||||
@@ -402,4 +399,4 @@
 | 
			
		||||
    </plugins>
 | 
			
		||||
  </reporting>
 | 
			
		||||
 | 
			
		||||
</project>
 | 
			
		||||
</project>
 | 
			
		||||
							
								
								
									
										33
									
								
								semaphore/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								semaphore/README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
---
 | 
			
		||||
layout: pattern
 | 
			
		||||
title: Semaphore
 | 
			
		||||
folder: semaphore
 | 
			
		||||
permalink: /patterns/semaphore/
 | 
			
		||||
categories: Lock
 | 
			
		||||
tags: 
 | 
			
		||||
 - Java
 | 
			
		||||
 - Difficulty-Beginner
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
## Also known as
 | 
			
		||||
Counting Semaphore
 | 
			
		||||
 | 
			
		||||
## Intent
 | 
			
		||||
Create a lock which mediates access to a pool of resources. 
 | 
			
		||||
Only a limited number of threads, specified at the creation 
 | 
			
		||||
of the semaphore, can access the resources at any given time.
 | 
			
		||||
A semaphore which only allows one concurrent access to a resource
 | 
			
		||||
is called a binary semaphore.
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
## Applicability
 | 
			
		||||
Use a Semaphore when 
 | 
			
		||||
 | 
			
		||||
* you have a pool of resources to allocate to different threads
 | 
			
		||||
* concurrent access to a resource could lead to a race condition 
 | 
			
		||||
 | 
			
		||||
## Credits
 | 
			
		||||
 | 
			
		||||
* [Semaphore(programming)] (http://en.wikipedia.org/wiki/Semaphore_(programming))
 | 
			
		||||
* [Semaphores] (http://tutorials.jenkov.com/java-concurrency/semaphores.html)
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								semaphore/etc/semaphore.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								semaphore/etc/semaphore.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 29 KiB  | 
							
								
								
									
										42
									
								
								semaphore/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								semaphore/pom.xml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<!--
 | 
			
		||||
 | 
			
		||||
    The MIT License
 | 
			
		||||
    Copyright (c) 2014 Ilkka Sepp<70>l<EFBFBD>
 | 
			
		||||
 | 
			
		||||
    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.
 | 
			
		||||
 | 
			
		||||
-->
 | 
			
		||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
 | 
			
		||||
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 | 
			
		||||
  <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
  <parent>
 | 
			
		||||
    <groupId>com.iluwatar</groupId>
 | 
			
		||||
    <artifactId>java-design-patterns</artifactId>
 | 
			
		||||
    <version>1.12.0-SNAPSHOT</version>
 | 
			
		||||
  </parent>
 | 
			
		||||
  <artifactId>semaphore</artifactId>
 | 
			
		||||
  <dependencies>
 | 
			
		||||
    <dependency>
 | 
			
		||||
      <groupId>junit</groupId>
 | 
			
		||||
      <artifactId>junit</artifactId>
 | 
			
		||||
      <scope>test</scope>
 | 
			
		||||
    </dependency>
 | 
			
		||||
  </dependencies>
 | 
			
		||||
</project>
 | 
			
		||||
							
								
								
									
										50
									
								
								semaphore/src/main/java/com/iluwatar/semaphore/App.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								semaphore/src/main/java/com/iluwatar/semaphore/App.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,50 @@
 | 
			
		||||
/**
 | 
			
		||||
 * 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;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A Semaphore mediates access by a group of threads to a pool of resources.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * In this example a group of customers are taking fruit from a fruit shop.
 | 
			
		||||
 * There is a bowl each of apples, oranges and lemons. Only one customer can 
 | 
			
		||||
 * access a bowl simultaneously. A Semaphore is used to indicate how many 
 | 
			
		||||
 * resources are currently available and must be acquired in order for a bowl 
 | 
			
		||||
 * to be given to a customer. Customers continually try to take fruit until 
 | 
			
		||||
 * there is no fruit left in the shop. 
 | 
			
		||||
 */
 | 
			
		||||
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();
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										76
									
								
								semaphore/src/main/java/com/iluwatar/semaphore/Customer.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								semaphore/src/main/java/com/iluwatar/semaphore/Customer.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,76 @@
 | 
			
		||||
/**
 | 
			
		||||
 * 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;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A Customer attempts to repeatedly take Fruit from the FruitShop by
 | 
			
		||||
 * taking Fruit from FruitBowl instances.
 | 
			
		||||
 */
 | 
			
		||||
public class Customer extends Thread {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Name of the Customer.
 | 
			
		||||
   */
 | 
			
		||||
  private final String name;
 | 
			
		||||
  
 | 
			
		||||
  /**
 | 
			
		||||
   * The FruitShop he is using.
 | 
			
		||||
   */
 | 
			
		||||
  private final FruitShop fruitShop;
 | 
			
		||||
  
 | 
			
		||||
  /**
 | 
			
		||||
   * Their bowl of Fruit.
 | 
			
		||||
   */
 | 
			
		||||
  private final FruitBowl fruitBowl;
 | 
			
		||||
  
 | 
			
		||||
  /**
 | 
			
		||||
   * Customer constructor
 | 
			
		||||
   */
 | 
			
		||||
  public Customer(String name, FruitShop fruitShop) {
 | 
			
		||||
    this.name = name;
 | 
			
		||||
    this.fruitShop = fruitShop;
 | 
			
		||||
    this.fruitBowl = new FruitBowl();
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  /**
 | 
			
		||||
   * The Customer repeatedly takes Fruit from the FruitShop until no Fruit
 | 
			
		||||
   * remains.
 | 
			
		||||
   */   
 | 
			
		||||
  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);
 | 
			
		||||
        
 | 
			
		||||
  }
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										60
									
								
								semaphore/src/main/java/com/iluwatar/semaphore/Fruit.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								semaphore/src/main/java/com/iluwatar/semaphore/Fruit.java
									
									
									
									
									
										Normal file
									
								
							@@ -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 is a resource stored in a FruitBowl. 
 | 
			
		||||
 */
 | 
			
		||||
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 "";
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,88 @@
 | 
			
		||||
/**
 | 
			
		||||
 * 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;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A FruitBowl contains Fruit. 
 | 
			
		||||
 */
 | 
			
		||||
public class FruitBowl {
 | 
			
		||||
    
 | 
			
		||||
  private ArrayList<Fruit> fruit = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 
 | 
			
		||||
   * @return The amount of Fruit left in the bowl. 
 | 
			
		||||
   */
 | 
			
		||||
  public int countFruit() {
 | 
			
		||||
    return fruit.size();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Put an item of Fruit into the bowl.
 | 
			
		||||
   * 
 | 
			
		||||
   * @param f fruit
 | 
			
		||||
   */
 | 
			
		||||
  public void put(Fruit f) {
 | 
			
		||||
    fruit.add(f);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  /**
 | 
			
		||||
   * Take an item of Fruit out of the bowl.
 | 
			
		||||
   * @return The Fruit taken out of the bowl, or null if empty.
 | 
			
		||||
   */
 | 
			
		||||
  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";
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										120
									
								
								semaphore/src/main/java/com/iluwatar/semaphore/FruitShop.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								semaphore/src/main/java/com/iluwatar/semaphore/FruitShop.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,120 @@
 | 
			
		||||
/**
 | 
			
		||||
 * 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;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A FruitShop contains three FruitBowl instances and controls access to them.
 | 
			
		||||
 */
 | 
			
		||||
public class FruitShop {
 | 
			
		||||
   
 | 
			
		||||
  /**
 | 
			
		||||
   * The FruitBowl instances stored in the class.
 | 
			
		||||
   */
 | 
			
		||||
  private FruitBowl[] bowls = {
 | 
			
		||||
    new FruitBowl(),
 | 
			
		||||
    new FruitBowl(),
 | 
			
		||||
    new FruitBowl()
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Access flags for each of the FruitBowl instances.
 | 
			
		||||
   */
 | 
			
		||||
  private boolean[] available = {
 | 
			
		||||
    true,
 | 
			
		||||
    true,
 | 
			
		||||
    true
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The Semaphore that controls access to the class resources.
 | 
			
		||||
   */
 | 
			
		||||
  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);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 
 | 
			
		||||
   * @return The amount of Fruit left in the shop.
 | 
			
		||||
   */
 | 
			
		||||
  public synchronized int countFruit() {
 | 
			
		||||
    return bowls[0].countFruit() + bowls[1].countFruit() + bowls[2].countFruit();
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  /**
 | 
			
		||||
   * Method called by Customer to get a FruitBowl from the shop. This method
 | 
			
		||||
   * will try to acquire the Semaphore before returning the first available 
 | 
			
		||||
   * FruitBowl.
 | 
			
		||||
   */   
 | 
			
		||||
  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;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  /**
 | 
			
		||||
   * Method called by a Customer instance to return a FruitBowl to the shop. 
 | 
			
		||||
   * This method releases the Semaphore, making the FruitBowl available to 
 | 
			
		||||
   * another Customer.
 | 
			
		||||
   */   
 | 
			
		||||
  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;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										34
									
								
								semaphore/src/main/java/com/iluwatar/semaphore/Lock.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								semaphore/src/main/java/com/iluwatar/semaphore/Lock.java
									
									
									
									
									
										Normal file
									
								
							@@ -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 is an interface for a lock which can be acquired and released.
 | 
			
		||||
 */
 | 
			
		||||
public interface Lock {
 | 
			
		||||
    
 | 
			
		||||
  void acquire() throws InterruptedException;
 | 
			
		||||
  
 | 
			
		||||
  void release();
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,77 @@
 | 
			
		||||
/**
 | 
			
		||||
 * 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 is an implementation of a semaphore lock.
 | 
			
		||||
 */
 | 
			
		||||
public class Semaphore implements Lock {
 | 
			
		||||
 | 
			
		||||
  private final int licenses;
 | 
			
		||||
  /**
 | 
			
		||||
   * The number of concurrent resource accesses which are allowed.
 | 
			
		||||
   */
 | 
			
		||||
  private int 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; 
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  /**
 | 
			
		||||
   * Method called by a thread to acquire the lock. If there are no resources
 | 
			
		||||
   * available this will wait until the lock has been released to re-attempt
 | 
			
		||||
   * the acquire.
 | 
			
		||||
   */
 | 
			
		||||
  public synchronized void acquire() throws InterruptedException {
 | 
			
		||||
    while (counter == 0) {
 | 
			
		||||
      wait();
 | 
			
		||||
    }
 | 
			
		||||
    counter = counter - 1;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  /**
 | 
			
		||||
   * Method called by a thread to release the lock.
 | 
			
		||||
   */
 | 
			
		||||
  public synchronized void release() {
 | 
			
		||||
    if (counter < licenses) {
 | 
			
		||||
      counter = counter + 1;
 | 
			
		||||
      notify();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										34
									
								
								semaphore/src/test/java/com/iluwatar/semaphore/AppTest.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								semaphore/src/test/java/com/iluwatar/semaphore/AppTest.java
									
									
									
									
									
										Normal file
									
								
							@@ -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;
 | 
			
		||||
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
 | 
			
		||||
public class AppTest{
 | 
			
		||||
  @Test
 | 
			
		||||
  public void test() throws IOException {
 | 
			
		||||
    String[] args = {};
 | 
			
		||||
    App.main(args);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -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());
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -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);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user