Created
December 2, 2011 14:43
-
-
Save noahlz/1423468 to your computer and use it in GitHub Desktop.
Example code for AbstractQueuedSychronizer. Something I wrote a few years back while reading Java Concurrency in Practice.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import java.util.concurrent.locks.AbstractQueuedSynchronizer; | |
| public class AqsSample { | |
| public static void main(String[] args) { | |
| Restroom restroom = new Restroom(); | |
| Thread larry = new Thread(new Patron("Larry",restroom)); | |
| Thread moe = new Thread(new Patron("Moe", restroom)); | |
| Thread curly = new Thread(new Patron("Curly", restroom)); | |
| Thread wanda = new Thread(new Attendant("Wanda", restroom)); | |
| larry.setName("Larry"); | |
| moe.setName("Moe"); | |
| curly.setName("Curly"); | |
| wanda.setName("Wanda"); | |
| larry.start(); | |
| moe.start(); | |
| curly.start(); | |
| wanda.start(); | |
| } | |
| } | |
| interface Door { | |
| void lock(); | |
| void unlock(); | |
| void open(); | |
| } | |
| abstract class Person { | |
| final String name; | |
| Person(String name) { | |
| this.name = name; | |
| } | |
| public String getName() { | |
| return name; | |
| } | |
| } | |
| class Attendant extends Person implements Runnable { | |
| private final Restroom restroom; | |
| Attendant(String name, Restroom restroom) { | |
| super(name); | |
| this.restroom = restroom; | |
| } | |
| public void run() { | |
| restroom.beCleanedBy(this); | |
| } | |
| } | |
| class Patron extends Person implements Runnable { | |
| private final Restroom restroom; | |
| Patron(String name, Restroom restroom) { | |
| super(name); | |
| this.restroom = restroom; | |
| } | |
| public void run() { | |
| walkToDoor(); | |
| restroom.beUsedBy(this); | |
| System.out.println(getName() + ": \"ahhhhhhh!\""); | |
| } | |
| private void walkToDoor() { | |
| System.out.println(getName() + " is walking towards the restroom door..."); | |
| try { | |
| Thread.sleep(1000L); | |
| } catch (InterruptedException ex) { | |
| // eh...ignore | |
| } | |
| } | |
| } | |
| class Restroom { | |
| private Door door = new RestroomDoor(); | |
| void beCleanedBy(Attendant wanda) { | |
| String name = ThreadUtils.getCurrentThreadName() ; | |
| System.out.println(name + " is cleaning the restroom..."); | |
| door.lock(); | |
| try { | |
| Thread.sleep(5000L); | |
| } | |
| catch (InterruptedException ex) { | |
| System.out.println(name + ": \"ok, ok, I'm finished!\""); | |
| } finally { | |
| System.out.println(name + ": \"the restroom is now available\""); | |
| door.unlock(); | |
| } | |
| } | |
| void beUsedBy(Patron patron) { | |
| String name = ThreadUtils.getCurrentThreadName(); | |
| System.out.println(name + " is trying to open the restroom door..."); | |
| door.open(); | |
| } | |
| } | |
| /** | |
| * A simple latch implementation. Adapted from Java Concurrency in Practice | |
| * by Brian Goetz, et. al. Listing 14.14 (p 313) | |
| */ | |
| class RestroomDoor extends AbstractQueuedSynchronizer implements Door { | |
| public void lock() { | |
| setState(-1); | |
| } | |
| public void unlock() { | |
| this.releaseShared(0); | |
| } | |
| public void open() { | |
| this.acquireShared(0); | |
| } | |
| protected int tryAcquireShared(int arg) { | |
| return getState() == 1 ? 1 : -1; | |
| } | |
| protected boolean tryReleaseShared(int arg) { | |
| setState(1); | |
| return true; | |
| } | |
| } | |
| class ThreadUtils { | |
| static String getCurrentThreadName() { | |
| return Thread.currentThread().getName(); | |
| } | |
| private ThreadUtils() {} | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment