diff --git a/event-queue/README.md b/event-queue/README.md
new file mode 100644
index 000000000..e69de29bb
diff --git a/event-queue/etc/Bass-Drum-1.wav b/event-queue/etc/Bass-Drum-1.wav
new file mode 100644
index 000000000..566181d94
Binary files /dev/null and b/event-queue/etc/Bass-Drum-1.wav differ
diff --git a/event-queue/etc/Closed-Hi-Hat-1.wav b/event-queue/etc/Closed-Hi-Hat-1.wav
new file mode 100644
index 000000000..2320db510
Binary files /dev/null and b/event-queue/etc/Closed-Hi-Hat-1.wav differ
diff --git a/event-queue/pom.xml b/event-queue/pom.xml
new file mode 100644
index 000000000..16ee381b3
--- /dev/null
+++ b/event-queue/pom.xml
@@ -0,0 +1,42 @@
+
+
+
+ 4.0.0
+
+ com.iluwatar
+ java-design-patterns
+ 1.16.0-SNAPSHOT
+
+ event-queue
+
+
+ junit
+ junit
+ test
+
+
+
diff --git a/event-queue/src/main/java/com/iluwatar/event/queue/App.java b/event-queue/src/main/java/com/iluwatar/event/queue/App.java
new file mode 100644
index 000000000..a84027ecb
--- /dev/null
+++ b/event-queue/src/main/java/com/iluwatar/event/queue/App.java
@@ -0,0 +1,67 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014-2016 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.event.queue;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.UnsupportedAudioFileException;
+
+/**
+ * Event or message queues provide an asynchronous communications protocol, meaning that the sender
+ * and receiver of the message do not need to interact with the message queue at the same time.
+ * Events or messages placed onto the queue are stored until the recipient retrieves them. Event
+ * or message queues have implicit or explicit limits on the size of data that may be transmitted
+ * in a single message and the number of messages that may remain outstanding on the queue.
+ * A queue stores a series of notifications or requests in first-in, first-out order.
+ * Sending a notification enqueues the request and returns. The request processor then processes
+ * items from the queue at a later time.
+ */
+public class App {
+ /**
+ * Program entry point.
+ *
+ * @param args command line args
+ * @throws IOException when there is a problem with the audio file loading
+ * @throws UnsupportedAudioFileException when the loaded audio file is unsupported
+ */
+ public static void main(String[] args) throws UnsupportedAudioFileException, IOException {
+ Audio.playSound(getAudioStream("./etc/Bass-Drum-1.wav"), -10.0f);
+ Audio.playSound(getAudioStream("./etc/Closed-Hi-Hat-1.wav"), -8.0f);
+
+ System.out.println("Press Enter key to stop the program...");
+ BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
+ br.read();
+ Audio.stopService();
+ }
+
+ public static AudioInputStream getAudioStream(String filePath)
+ throws UnsupportedAudioFileException, IOException {
+ return AudioSystem.getAudioInputStream(new File(filePath).getAbsoluteFile());
+ }
+}
diff --git a/event-queue/src/main/java/com/iluwatar/event/queue/Audio.java b/event-queue/src/main/java/com/iluwatar/event/queue/Audio.java
new file mode 100644
index 000000000..a9f0c5a67
--- /dev/null
+++ b/event-queue/src/main/java/com/iluwatar/event/queue/Audio.java
@@ -0,0 +1,131 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014-2016 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.event.queue;
+
+import java.io.IOException;
+
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.LineUnavailableException;
+
+/**
+ * This class implements the Event Queue pattern.
+ * @author mkuprivecz
+ *
+ */
+public class Audio {
+
+ private static final int MAX_PENDING = 16;
+
+ private static int headIndex;
+
+ private static int tailIndex;
+
+ private static Thread updateThread = null;
+
+ private static PlayMessage[] pendingAudio = new PlayMessage[MAX_PENDING];
+
+ public static boolean isServiceRunning() {
+ return updateThread.isAlive();
+ }
+
+ /**
+ * This method stops the Update Method's thread.
+ */
+ public static void stopService() {
+ if (updateThread != null) {
+ updateThread.interrupt();
+ }
+ }
+
+ /**
+ * Starts the thread for the Update Method pattern if it was not started previously.
+ * Also when the thread is is ready initializes the indexes of the queue
+ */
+ public static void init() {
+ if (updateThread == null) {
+ updateThread = new Thread(new Runnable() {
+ public void run() {
+ while (!Thread.currentThread().isInterrupted()) {
+ Audio.update();
+ }
+ }
+ });
+ }
+ if (!updateThread.isAlive()) {
+ updateThread.start();
+ headIndex = 0;
+ tailIndex = 0;
+ }
+ }
+
+ /**
+ * This method adds a new audio into the queue.
+ * @param stream is the AudioInputStream for the method
+ * @param volume is the level of the audio's volume
+ */
+ public static void playSound(AudioInputStream stream, float volume) {
+ init();
+ // Walk the pending requests.
+ for (int i = headIndex; i != tailIndex; i = (i + 1) % MAX_PENDING) {
+ if (pendingAudio[i].stream == stream) {
+ // Use the larger of the two volumes.
+ pendingAudio[i].volume = Math.max(volume, pendingAudio[i].volume);
+
+ // Don't need to enqueue.
+ return;
+ }
+ }
+ pendingAudio[tailIndex] = new PlayMessage();
+ pendingAudio[tailIndex].stream = stream;
+ pendingAudio[tailIndex].volume = volume;
+ tailIndex = (tailIndex + 1) % MAX_PENDING;
+ }
+
+ /**
+ * This method uses the Update Method pattern.
+ * It takes the audio from the queue and plays it
+ */
+ public static void update() {
+ // If there are no pending requests, do nothing.
+ if (headIndex == tailIndex) {
+ return;
+ }
+ Clip clip = null;
+ try {
+ clip = AudioSystem.getClip();
+ clip.open(pendingAudio[headIndex].stream);
+ } catch (LineUnavailableException e) {
+ System.err.println("Error occoured while loading the audio: The line is unavailable");
+ e.printStackTrace();
+ } catch (IOException e) {
+ System.err.println("Input/Output error while loading the audio");
+ e.printStackTrace();
+ }
+ clip.start();
+
+ headIndex++;
+ }
+}
diff --git a/event-queue/src/main/java/com/iluwatar/event/queue/PlayMessage.java b/event-queue/src/main/java/com/iluwatar/event/queue/PlayMessage.java
new file mode 100644
index 000000000..5d151e8d5
--- /dev/null
+++ b/event-queue/src/main/java/com/iluwatar/event/queue/PlayMessage.java
@@ -0,0 +1,36 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014-2016 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.event.queue;
+
+import javax.sound.sampled.AudioInputStream;
+
+/**
+ * The Event Queue's queue will store the instances of this class.
+ * @author mkuprivecz
+ *
+ */
+public class PlayMessage {
+ AudioInputStream stream;
+ float volume;
+}
diff --git a/pom.xml b/pom.xml
index 4b9740857..bca17e99a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -133,6 +133,7 @@
promise
page-object
event-asynchronous
+ event-queue
queue-load-leveling
object-mother
converter