001    package railo.commons.lang.lock;
002    
003    public final class KeyLock {
004            
005            private final Token token=new Token();
006            private KeyLockListener listener;
007    
008            public KeyLock() {
009                    this.listener=NullKeyLockListener.getInstance();
010            }
011            public KeyLock(KeyLockListener listener) {
012                    this.listener=listener;
013            }
014    
015            public void start(String key) {
016                    while(true) {
017                            // nobody inside
018                            
019                            synchronized(token) {
020                                    if(token.value==null) {
021                                            token.value=key;
022                                            token.count++;
023                                            listener.onStart(token.value,true);      
024                                            return;
025                                    }
026                                    if(key.equalsIgnoreCase(token.value)) {
027                                            token.count++;
028                                            listener.onStart(token.value,false);      
029                                            return;
030                                    }
031                                    try {
032                                            token.wait();
033                                    } 
034                                    catch (InterruptedException e) {}
035                            }
036                    }
037            }
038            
039            public void end() {
040                    synchronized(token) {
041                            if(--token.count<=0) {
042                                    listener.onEnd(token.value,true);    
043                                    if(token.count<0)token.count=0;
044                                    token.value=null;
045                            }
046                            else listener.onEnd(token.value,false); 
047                            token.notify();
048                    }
049            }
050            
051            public void setListener(KeyLockListener listener) { 
052                    this.listener=listener;
053            }
054            
055            
056            
057            
058    }
059    
060    class Token {
061            int count=0;
062            String value=null;
063    }
064