Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I don't want to use synchronized for sizeof method, any suggestion to implement the method thread safe?

package com.r.collection.adt;

import java.util.concurrent.atomic.AtomicReference;


public class ConcurrentStack<E> implements Stack<E>{

    @SuppressWarnings("hiding")
    private class Node<E>{

        public E item;
        public Node<E> next;

        public Node(E item){
            this.item=item;
        }

    }

    @SuppressWarnings("rawtypes")
    private AtomicReference<Node> head;

    @SuppressWarnings("rawtypes")
    ConcurrentStack(){
        head = new AtomicReference<Node>();
    }

    @SuppressWarnings("unchecked")
    @Override
    public void push(E item) {
        Node<E> newHead = new Node<E>(item);
        Node<E> headNode = null;
        do
        {
            headNode = head.get();
            newHead.next = headNode;
        }while(!head.compareAndSet(headNode, newHead));

    }


    @SuppressWarnings("unchecked")
    @Override
    public E pop() {
        Node<E> headNode = head.get();
        do
        {
            headNode = head.get();
            if(headNode == null)
                return null;
        }while(!head.compareAndSet(headNode, headNode.next));

        return headNode.item;
    }

    @SuppressWarnings("unchecked")
    @Override
    public E peek() {
        Node<E> headNode = head.get();
        if(headNode == null){
            return null;
        }

        return headNode.item;
    }

    @Override
    public boolean isEmpty() {

        return head.get() == null;
    }

    @SuppressWarnings("unchecked")
    @Override
    public synchronized int  sizeOf() {
        int size=0;
        for(Node<E> node=head.get();node != null; node=node.next){
            size++;
        }
        return size;
    }

}
share|improve this question

The synchronization you are currently using is not even working the way you intend to: as nothing else is synchronizing on this (like the sizeOf() method) you might as well not make the method synchronized.

You could stick a size field into your Node which gets set on inserting, something along the lines of this:

do {
    headNode = head.get();
    newHead.next = headNode;
    newHead.size = (headNode == null) ? 1 : headNode.size + 1;
} while (!head.compareAndSet(headNode, newHead));

This should allow reduction of the sizeOf() method to:

public int sizeOf() {
    return head.get().size;
}
share|improve this answer
    
yes we can use size in Node class but it would be available in every node(every item) and occupy space. – ganesh r Mar 12 at 12:02
    
Well, you haven’t mentioned that particular requirement. If you keep changing what you want nobody can help you. You either need to invest the space to save time, or you need to invest time to save space. – Bombe Mar 12 at 12:11
    
am not changing my requirement. i want to implement size of method thread safe in better way. – ganesh r Mar 12 at 12:24
    
And I just showed you how to do that. – Bombe Mar 12 at 12:44

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.