Java Component Examples

LockFreeEBDeque Example

/*
 * Copyright (c) 2008 IBM Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.amino.examples;

/*   The Deque is a double-ended queue, elements can only be added to
 *   or removed from the front (head) or back (tail).
 *   This example shows the mainly interfaces of EBDeque which adds
 *   elimination mechanism to deal with high contention rate scenario.
 *   Including : element(), offer(), peek(), poll(), iterator(),
 *               getFirst(), getLast(), add(), clear(), removeFist(), removeLast()
 *  
 *   The DequeAdder class will add items of String from "1" to "ELEMENT_NUM".
 *   The DequeRemover class will remove no more than ELEMENT_NUM items.
 *   The main thread will wait for all the threads in pool to finish.  
 *   2009/05/22
 */

import java.util.Deque;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.Iterator;

import org.amino.ds.lockfree.EBDeque;

public class EBDequeExample {

    public static final int ELEMENT_NUM = 100;
    private static final int TASKS_NUM = 4;
    public static void main(String[] argvs) {

        ExecutorService exec = Executors.newFixedThreadPool(TASKS_NUM);

        final EBDeque<String> dequeStr = new EBDeque<String>();

        for (int i = 0; i < TASKS_NUM; ++i) {
            exec.submit(new DequeAdder(dequeStr));
            if (i%2 == 0)exec.submit(new DequeRemover(dequeStr));
        }

        exec.shutdown();
        
        // Wait until all the threads in pool to finish.
        try {
            while(!exec.awaitTermination(600, TimeUnit.SECONDS));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    
        // If the Deque is empty now, the program will exit.
        if (dequeStr.isEmpty())
        {
            System.out.println("The Deque is empty, so I will exit!");
            System.exit(1);
        }
        
        String first = dequeStr.poll();
        dequeStr.addFirst(first);
        
        String first1 = dequeStr.removeFirst();
        assert(first == first1);
        
        // The offer*() has the same functionality as add*().
        dequeStr.offerLast(first1);
        String last = dequeStr.peekLast();
        String last1 = dequeStr.getLast();
        String last2 = dequeStr.pollLast();
        assert(last == last1 && last1 == last2 && first1 == last);
        
        dequeStr.addLast(first1);
        last = dequeStr.peekLast();
        last1 = dequeStr.getLast();
        last2 = dequeStr.pollLast();
        assert(last == last1 && last1 == last2 && first1 == last);

                
        // Print all the elements in Deque.
        for (String str : dequeStr)
            System.out.println(str);
            
        System.out.println("Deque size before clearing: "+ dequeStr.size());
        dequeStr.clear();
        System.out.println("Deque size after clearing: "+ dequeStr.size());
    }
}

/*
 *  The DequeAdder class will add elements to the given Deque.
 */
class DequeAdder implements Runnable {
    Deque<String> taskDq;
    private int count = 0;
    
    public DequeAdder(EBDeque<String> taskDeque)
    {
        taskDq = taskDeque;    
    }
        
    public void run(){
        while (count < EBDequeExample.ELEMENT_NUM)
        {
            // The add* functions have no return value.
            taskDq.addFirst(Integer.toString(count++));
            taskDq.addLast(Integer.toString(count));
            System.out.println(Thread.currentThread()+ " Added first and last:" + count);
            
            // The offer* functions have boolean return value.
            if (!taskDq.offerFirst(Integer.toString(count++)))
                System.out.println("offerFirst() failed!");
            if (!taskDq.offerLast(Integer.toString(count)))
                System.out.println("offerFirst() failed!");                    
            System.out.println(Thread.currentThread()+ " Offered first and last:" + count);          
        }
        Thread.yield();
    }  
}

/*
 *  The DequeRemover class will remove the existed elements from the given Deque.
 */
class DequeRemover implements Runnable {
    Deque<String> taskDq;
    
    public DequeRemover(EBDeque<String> taskDeque)
    {
        taskDq = taskDeque;    
    }
        
    public void run(){
        int times = 0;
        
        while (times < EBDequeExample.ELEMENT_NUM)
        {
            String toRemoveFirst = taskDq.removeFirst();
            String toRemoveLast = taskDq.removeLast();
            System.out.println(Thread.currentThread()+ " Removed first: " + toRemoveFirst);
            System.out.println(Thread.currentThread()+ " Removed last: " + toRemoveLast);
            times++;
        }
        Thread.yield();
    }  
}
Back Home