Singleton holding and notifying registered listeners Suppose I am listening for network changes with the following listener:

interface NetListener {

    void onNetworkAvailable(boolean isWifi);

    void onNetworkUnavailable();
}


I want to have an object, accessible from anywhere within the app, holding the registered NetListeners, that can trigger the appropriate methods when necessary. The solution I came up with is this "singleton": 

class NetListenerManager {

    private static List&lt;NetListener&gt; _listeners = new CopyOnWriteArrayList&lt;NetListener&gt;();

    static void addListener(final NetListener listener) {
        if (null != listener) { _listeners.add(listener); }
    }

    static void removeListener(final NetListener listener) {
        if (null != listener) { _listeners.remove(listener); }
    }

    /**
     * Called when a network connection is available.
     */
    static void notifyOnNetworkAvailable(boolean isWifi) {
        for (NetListener listener : _listeners) { listener.onNetworkAvailable(isWifi); }
    }

    /**
     * Called when a network connection becomes unavailable.
     */
    static void notifyOnNetworkUnavailable() {
        for (NetListener listener : _listeners) { listener.onNetworkUnavailable(); }
    }

    private NetListenerManager() { /* Instantiation disabled. */ }

}


So whenever e.g. a network change broadcast is received, I call NetListenerManager.notifyOnNetworkAvailable or NetListenerManager.notifyOnNetworkUnavailable, 
depending on the network state. 

I’m wondering if this is a good solution or if there are better ways to implement this. 
Thanks!

UPDATE no.2

This is the modified listener: 

interface NetListener {

    static enum NetworkType {NO_NETWORK, WIFI, MOBILE}

    void onNetworkChange(NetworkType type);

}


And the manager:

public final class NetListenerManager {

    private static final List&lt;NetListener&gt; NET_LISTENERS = new CopyOnWriteArrayList&lt;NetListener&gt;();
    private static final BlockingQueue&lt;NetListener.NetworkType&gt; QUEUE = new LinkedBlockingQueue&lt;NetListener.NetworkType&gt;();

    private static final Thread QUEUE_PROCESSOR = new Thread(new QueueProcessor());
    static { QUEUE_PROCESSOR.start(); }


    public static void addListener(final NetListener listener) {
        if (null != listener) { NET_LISTENERS.add(listener); }
    }

    public static void removeListener(final NetListener listener) {
        if (null != listener) { NET_LISTENERS.remove(listener); }
    }

    /**
     * Called when there is a network change.
     */
    public static void notifyOnNetworkChange(final NetListener.NetworkType type) {
        QUEUE.add(type);
    }

    private NetListenerManager() { /* Instantiation disabled. */ }

    /**
     * This Runnable propagates network change events to the registered NetListener listeners in a queue.
     */
    private static final class QueueProcessor implements Runnable {
        @Override
        public void run() {
            while (true) {
                try {
                    final NetListener.NetworkType type = QUEUE.take();
                    for (NetListener listener : NET_LISTENERS) { listener.onNetworkChange(type); }
                } catch (InterruptedException ie) { /* Do nothing */ }
            }
        }
    }

}
(Disclaimer: I posted this as a comment first but feel like it should also be an answer)

You should consider to use enum as a singleton as proposed by Joshua Blochs in Effective Java. This will protect you from both serialization attacks and reflection attacks on your singleton instance. 

Here is a post which discusses it a lot more in-depth.
https://stackoverflow.com/questions/70689/what-is-an-efficient-way-to-implement-a-singleton-pattern-in-java/71399#71399