Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/yaftp/utils/TokenSemaphore.java


1    /**
2    *
3    * CopyRights Jean-Yves MENGANT 1999,2000,2001,2002
4    *
5    * This program is free software; you can redistribute it and/or
6    * modify it under the terms of the GNU General Public License
7    * as published by the Free Software Foundation; either version 2
8    * of the License, or any later version.
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with this program; if not, write to the Free Software
17   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18   */
19  
20  package com.yaftp.utils;
21  
22  /**
23  
24    Copyright Jean-Yves MENGANT 1998,1999,2000
25  
26    This class implements a MUTUAL EXCLUSIVE semaphore
27    access using internal _tokenIsReady flag
28    use this to synchronize concurent access to a single
29    ressource
30  
31    Implementation is based on OReilly JAVA THREAD book examples
32  
33    @author Jean-Yves MENGANT
34  
35  */
36  
37  public class TokenSemaphore {
38  
39    transient private int     _busyCount = 0     ;
40    transient private Thread  _owner     = null  ;
41    transient private String  _name              ;
42    transient private boolean _debug     = false ;
43  
44    public final static boolean _SET_BUSY_ = true  ;
45    public final static boolean _SET_FREE_ = false ;
46  
47    public final static boolean _DEBUG_MODE_ = true ;
48  
49    public void set_debug( boolean debug )
50    { _debug = debug ; }
51  
52    private void debug( String dbg )
53    {
54      System.out.println( Thread.currentThread() + dbg ) ;
55    }
56  
57    private void initInstance( String  name ,
58                               boolean tokenState
59                             )
60    {
61    //  if ( _debug )
62    //    debug("entering construction for : "+name+this) ;
63  
64      _name = name ;
65  
66      if ( tokenState ) // if true => owning Token is requested by thread
67        waitForSemaphore() ;
68  
69    //  if ( _debug )
70    //    debug("leaving construction for : "+name+this) ;
71    }
72  
73    /** basic constructor */
74    public TokenSemaphore( String  name        ,
75                           boolean tokenState
76                         )
77    {
78      initInstance(name,tokenState) ;
79    }
80  
81    /** debug Constructor */
82    public TokenSemaphore( String  name        ,
83                           boolean tokenState  ,
84                           boolean debug
85                         )
86    {
87      set_debug(debug) ;
88      initInstance(name,tokenState) ;
89    }
90  
91    private synchronized Thread getBusyCountOwner()
92    {
93      return _owner ;
94    }
95  
96    /** request token primitive */
97    private synchronized boolean tryGetToken()
98    {
99    //  if ( _debug )
100   //    debug("entering TryGetToken") ;
101 
102     if ( _owner == null )
103     {
104   //    if ( _debug )
105   //      debug( " will Own "+ _name + "." + this ) ;
106       _owner = Thread.currentThread() ;
107       _busyCount = 1 ;
108       return true    ;
109     }
110 
111     if ( _owner == Thread.currentThread() )
112     {
113       _busyCount++  ;
114 
115   //    if ( _debug )
116   //      debug( " increments counter " + _busyCount
117   //            + " on " + _name + "." + this ) ;
118       return true ;
119     }
120 
121   //  if ( _debug )
122   //    debug( " " + this + " is owned by : " + _owner )  ;
123 
124   //  if ( _debug )
125   //    debug(" leaving TryGetToken : nothing done") ;
126 
127     return false ;
128   }
129 
130   /** wait for synchronized ressource */
131   public synchronized void waitForSemaphore()
132   {
133   //  if ( _debug )
134   //    debug( " waits for sem on : " + _name + "." + this ) ;
135 
136     while ( tryGetToken() == false  )
137       try {
138    //     if ( _debug )
139    //       debug( " before wait()") ;
140 
141         wait() ;
142 
143    //     if ( _debug )
144    //      debug( " END OF WAIT for :"+this) ;
145       } catch ( InterruptedException e ){}
146 
147    // if ( _debug )
148    //   debug( " leaving waitForSem") ;
149   }
150 
151   /** free synchronized ressource */
152    public synchronized void freeSemaphore()
153    {
154    //  if ( _debug )
155    //    debug( " entering freeSemaphore") ;
156 
157      if ( getBusyCountOwner() == Thread.currentThread() )
158      {
159    //    if ( _debug )
160    //      debug( " decrements counter " + _busyCount ) ;
161        _busyCount-- ;
162        if ( _busyCount == 0 )
163        {
164          _owner = null ;
165    //      if ( _debug )
166    //        debug(" NO MORE OWNING : "+ _name + "." + this ) ;
167          notify() ;
168        }
169      }
170    //  else
171    //    if ( _debug )
172    //      debug( " NOT FREED owner is : " + _owner ) ;
173 
174    //  if ( _debug )
175    //    debug( " leaving freeSemaphore") ;
176    }
177 
178    /**
179      put a clean waiting process when a thread is
180      waiting upon another thread getting ressource
181      property
182    */
183    public void waitForOwning( Thread owner )
184    {
185    //  if ( _debug )
186    //    debug( " waiting for "
187    //           + owner + " to own instead of "
188    //           + _owner
189    //         ) ;
190 
191      while ( getBusyCountOwner() != owner )
192      {
193        Thread.yield()  ;
194        try {
195          Thread.sleep(1) ;
196        } catch ( InterruptedException e ){} ;
197      }
198 
199    // if ( _debug )
200    //   debug( " leaving waitforOwning " );
201    }
202 
203    /** returns true if object is belonging to some thread */
204    public synchronized boolean isBusy ()
205    { return ( _owner != null ) ; }
206 
207   /**
208   Unit Testing semaphores
209   */
210   public static void main ( String arg[] )
211   {
212     RunnerWaiter runwait = new RunnerWaiter() ;
213 
214 
215     _PRIMARY_   primary    = new _PRIMARY_ (runwait)  ;
216     _SECONDARY_ secondary  = new _SECONDARY_(runwait) ;
217 
218     primary.start() ;
219     secondary.start() ;
220   }
221 }
222 
223 // internal unit test classes
224 // The primary
225 class _PRIMARY_ extends Thread {
226   RunnerWaiter _cur ;
227   long         _count = 0 ;
228 
229   public _PRIMARY_(  RunnerWaiter cur )
230   {  super("_PRIMARY_") ;
231     _cur = cur ;
232   }
233 
234   public void run()
235   {
236   long testNum = 0 ;
237     System.out.println("PRIMARY started") ;
238     while  ( true )
239     {
240       _cur.startRUNNER() ;
241 
242       System.out.println( Thread.currentThread().getName() +
243                      "ENTERING RUNNER :" + _count +
244                      " memory : " +
245                      Runtime.getRuntime().freeMemory() ) ;
246       _count++  ;
247       for (int ii = 1 ; ii < 100 ; ii++ ) ;
248       try {
249         Thread.sleep(100) ;
250       } catch ( InterruptedException e ) {}
251 
252 
253       _cur.stopRUNNER() ;
254     }
255   }
256 } ;
257 
258     class _SECONDARY_ extends Thread {
259       RunnerWaiter _cur ;
260       long _count = 0   ;
261 
262       public _SECONDARY_( RunnerWaiter cur )
263       { super("_SECONDARY_") ;
264         _cur = cur ;
265       }
266 
267       public void run()
268       {
269       long testNum = 0 ;
270         System.out.println("SECONDARY started") ;
271         while  ( true )
272         {
273           _cur.startWAITER() ;
274 
275           System.out.println( Thread.currentThread().getName() +
276                          "ENTERING WAITER count :" + _count +
277                          " memory : " +
278                          Runtime.getRuntime().freeMemory()
279                          ) ;
280           _count++  ;
281            for (int ii = 1 ; ii < 100000 ; ii++ ) ;
282 
283           _cur.stopWAITER() ;
284         }
285       }
286     } ;