The Artima Developer Community
Sponsored Link

Design Forum
Singelton & JUnit tests

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Thomas SMETS

Posts: 307
Nickname: tsmets
Registered: Apr, 2002

Singelton & JUnit tests Posted: Sep 4, 2003 3:15 PM
Reply to this message Reply
Advertisement
For a element of code we have to write, a Buffer of Strings needs to be created. There is basically one Thread reading files & parsing them (Dom-elements as String). On another side there are Threads reading from the "buffer".
The current implementation seems fine : Please comment in case you find issues.
I tested the code this afternoon & it doesn't deadlock neither doesn't it seem to be slow ! Starving or queuing under some regular condition (Poper too fasts/slow or Pushers ...) but I would like to prove it with unit tests...

Here comes the problem : How can I test the close() more than once ?

I currently introduced in the code some methods that I don't like to see in there... Namely :
    void reOpen ()
    {
        log.info ("!!! !!! !!! void reOpen () !!! !!! !!!");
        isClosed = false;
    }
    
    void flush ()
        throws IOException
    {
        if (isClosed)
        {
            String msg = "Holder was closed";
            log.warn (msg);
            //throw new IOException (msg);    
        }
        in = null;
        out = null;
    } 


I definitively don't see how I could do that differently than introduce those methods that allow me to manipulate the internals of the instance while not opening those too much to the outside world.

Tx for your Help !

\T,


___________________________________
/*
 * Created on 14-Aug-2003
 *
 */
package com.tls.util.common;
 
import java.io.IOException;
 
import org.apache.log4j.Logger;
 
import com.tls.util.Helper;
 
 
/**
 * 
 * 
 * @author Thomas SMETS
 *
 */
public class StringBufferer
{
    private static final Logger log = Logger.getLogger (StringBufferer.class);
    public static final String ELEMENTS_STACK_SIZE = "ELEMENTS_STACK_SIZE";
    public static final int DEFAULT_STACK_SIZE = 4096;
    public static final int START_IN = -1;
    public static final int START_OUT = -1;
    
    /**
     * The fact that we create the <code>instance</code> reference makes it 
     * Thread-safe inherently.
     */
    private static final StringBufferer instance = new StringBufferer ();
    
    private String [] in = null, 
                     out = null;
    private Object inLock = new Object (),
                    outLock = new Object ();       
                         
    private int stackSize = DEFAULT_STACK_SIZE;    
    private int stackSizeLimit = DEFAULT_STACK_SIZE - 1;
 
    private int inPos = START_IN, 
                outPos = stackSizeLimit;
                
    private boolean isClosed = false;                
    
    /**
     * Hidden constructor     
     */
    StringBufferer ()
    {
        log.info ("Created");
        String property = System.getProperty(ELEMENTS_STACK_SIZE);
        try
        {            
            stackSize = Integer.parseInt( property ); 
        } catch (NumberFormatException nfe)
        {
            log.warn ("Number format Exception. Property value was : " + property, nfe);
            stackSize = DEFAULT_STACK_SIZE;
        }
        stackSizeLimit = stackSize - 1 ;
        outPos = stackSizeLimit;
    }
    
    /**
     * Singelton thread safe.
     * 
     * @return
     */
    public static StringBufferer getInstance ()
    {
        return instance;
    }
    
    /**
     * 
     * 
     * @param aDomeElementAsString
     */
    public void put (String aDomeElementAsString)
        throws IOException
    {
        if (aDomeElementAsString==null)
            return;
        
        if (isClosed)
        {        
            log.error ("Stack closed...");
            throw new IOException ("Stack closed");            
        }
            
        log.debug ("Putting : " + aDomeElementAsString);
        while (inPos==stackSizeLimit)
        {    
            checkSwapNeeded();
            synchronized (inLock)
            {                                           
                try
                {                
                    log.debug ("Waiting that some free space is made available");
                    inLock.wait ();
                    log.debug ("Woken up ! There might be some free space");                    
                } catch (InterruptedException ie)
                {
                    log.info ( "Thread has been interrupted. Message is " + ie.getMessage(),
                               ie );
                }        
            }
        }     
        if (in == null)
            in = new String[stackSize];            
        
        in[++inPos] = aDomeElementAsString;                                       
        
        checkSwapNeeded ();             
    }
    
    /**
     * 
     * 
     * @return the String
     */
    public String get ()
    {
        log.debug ("Retrieving the next element");
        while ( out==null | outPos == stackSizeLimit)
        {    
            try
            {   
                synchronized (inLock)
                {                                   
                   log.debug( "About to starve... I'll wake up a few waiting on the inLock" );                                        
                   inLock.notifyAll ();                                  
                }            
                synchronized (outLock)
                {                                   
                   log.debug( "Starving" );                                        
                   outLock.wait (100);                                  
                }
                
            } catch (InterruptedException ie)
            {
                log.warn ( "Somebody interrupted during my sleep. Message : " + ie.getMessage(), 
                           ie);
            }
        }
        return (out[++outPos]);                             
    }
        
    /**
     * This method estimates if a <code>swap</code> between the <code>in</code> 
     * &amp; the <code>out</code> may be needed
     * 
     *
     */
    private void checkSwapNeeded ()
    {
        if (inPos==stackSizeLimit & outPos==stackSizeLimit)
            swap ();    
    }
    
    private void swap ()
    {
        synchronized (outLock)
        {
            log.debug ("Swapping");
            out = in;
            inPos = START_IN;                
            outPos = START_OUT; 
            log.debug ("outLock.notifyAll()");
            outLock.notifyAll();            
        }   
        
        synchronized (inLock)
        {            
            log.debug ("inLock.notifyAll()");
            inLock.notifyAll();                                        
        }
    }
    
    /**
     * This is to be invoked whenever the Reader has finished to <code>put ()</code> 
     * element on the stack.
     */
    public void close ()
    {
        log.info ("Closing the DOMHolder");
        isClosed = true;
    }
    
    void reOpen ()
    {
        log.info ("!!! !!! !!! void reOpen () !!! !!! !!!");
        isClosed = false;
    }
    
    /**
     *      
     *
     */
    void flush ()
        throws IOException
    {
        if (isClosed)
        {
            String msg = "Holder was closed";
            log.warn (msg);
            //throw new IOException (msg);    
        }
        in = null;
        out = null;
    }
    
    /**
     * @see Object#toString
     */
    public String toString ()
    {
        StringBuffer buf = new StringBuffer ( 2 * stackSize * 50);
        String[] inCopy = new String[stackSize], 
                 outCopy = new String[stackSize];
        int inSize = 0,
            outSize = 0;
        Helper hlpr = Helper.getInstance();
            
                             
        synchronized (inLock)
        {
            System.arraycopy(in, 0, inCopy, 0, inSize = inPos);
        }
 
        synchronized (outLock)
        {
            System.arraycopy(out, 0, outCopy, 0, outSize = outPos);     
        }
        
        int i = 1;
        buf.append("in = ")
            .append (hlpr.showArray(inCopy))
            .append (Helper.LINE_SEPARATOR)
            .append ("out = ")
            .append (hlpr.showArray(outCopy))
            .append (Helper.LINE_SEPARATOR);
        
            
        return buf.toString ();
    }
    
    /**
     * @return
     */
    public int getStackSize ()
    {
      return stackSize;
    }
 
}
 

Topic: Implementing Aggregation in java Previous Topic   Next Topic Topic: please i need help

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use