alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (DoubleCheckedInt.java)

This example Java source code file (DoubleCheckedInt.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

brokenbarrierexception, cyclicbarrier, doublecheckedint, failure, illegalstateexception, interruptedexception, number_of_states, ongoing_initialization, state, stateaccessingthread, success, thread_count, threading, threads, uninitialized_state

The DoubleCheckedInt.java Java example source code

package org.slf4j;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

/**
 * This class demonstrates that threads accessing the STATE variable always see a consistent value. 
 * 
 * During ongoing initialization the observed value is either ONGOING_INITIALIZATION
 * or one of {SUCCESS, FAILURE}. 
 * 
 * Post initialization the observed value is always one of  {SUCCESS, FAILURE}.
 * 
 * See also http://jira.qos.ch/browse/SLF4J-167 
 * 
 * @author ceki
 *
 */
public class DoubleCheckedInt {

    final static int THREAD_COUNT = 10 + Runtime.getRuntime().availableProcessors() * 2;
    final static int UNINITIALIZED_STATE = 0;
    final static int ONGOING_INITIALIZATION = 1;
    final static int SUCCESS = 2;
    final static int FAILURE = 3;
    final static int NUMBER_OF_STATES = FAILURE + 1;

    private static int STATE = UNINITIALIZED_STATE;

    public static int getState() {
        if (STATE == 0) {
            synchronized (DoubleCheckedInt.class) {
                if (STATE == UNINITIALIZED_STATE) {
                    STATE = ONGOING_INITIALIZATION;
                    long r = System.nanoTime();
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                    }
                    if (r % 2 == 0) {
                        STATE = SUCCESS;
                    } else {
                        STATE = FAILURE;
                    }
                }
            }
        }
        return STATE;
    }

    static public void main(String[] args) throws InterruptedException, BrokenBarrierException {
        StateAccessingThread[] preInitializationThreads = harness();
        check(preInitializationThreads, false);

        System.out.println("============");
        StateAccessingThread[] postInitializationThreads = harness();
        check(postInitializationThreads, true);
    }

    private static StateAccessingThread[] harness() throws InterruptedException, BrokenBarrierException {
        StateAccessingThread[] threads = new StateAccessingThread[THREAD_COUNT];
        final CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1);
        for (int i = 0; i < THREAD_COUNT; i++) {
            threads[i] = new StateAccessingThread(barrier);
            threads[i].start();
        }

        barrier.await();
        for (int i = 0; i < THREAD_COUNT; i++) {
            threads[i].join();
        }
        return threads;
    }

    private static void check(StateAccessingThread[] threads, boolean postInit) {

        int[] stateCount = getStateCount(threads);
        printStateCount(stateCount);

        if (stateCount[UNINITIALIZED_STATE] != 0) {
            throw new IllegalStateException("getState() should never return a zero value");
        }

        if (stateCount[SUCCESS] != 0 && stateCount[FAILURE] != 0) {
            throw new IllegalStateException("getState() should return consistent values");
        }

        if (postInit) {
            if (stateCount[SUCCESS] != THREAD_COUNT && stateCount[FAILURE] != THREAD_COUNT) {
                throw new IllegalStateException("getState() should return consistent values");
            }
        }

    }

    private static void printStateCount(int[] stateCount) {
        for (int i = 0; i < NUMBER_OF_STATES; i++) {
            switch (i) {
            case UNINITIALIZED_STATE:
                System.out.println("UNINITIALIZED_STATE count: " + stateCount[i]);
                break;
            case ONGOING_INITIALIZATION:
                System.out.println("ONGOING_INITIALIZATION count: " + stateCount[i]);
                break;
            case SUCCESS:
                System.out.println("SUCCESS count: " + stateCount[i]);
                break;
            case FAILURE:
                System.out.println("FAILURE count: " + stateCount[i]);
                break;
            }
        }
    }

    private static int[] getStateCount(StateAccessingThread[] threads) {
        int[] valCount = new int[NUMBER_OF_STATES];
        for (int i = 0; i < threads.length; i++) {
            int val = threads[i].state;
            valCount[val] = valCount[val] + 1;
        }
        return valCount;
    }

    static class StateAccessingThread extends Thread {
        public int state = -1;
        final CyclicBarrier barrier;

        StateAccessingThread(CyclicBarrier barrier) {
            this.barrier = barrier;
        }

        public void run() {
            try {
                barrier.await();
            } catch (Exception e) {
                e.printStackTrace();
            }
            state = DoubleCheckedInt.getState();
        }
    };
}

Other Java examples (source code examples)

Here is a short list of links related to this Java DoubleCheckedInt.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.