单例模式在不同的线程中使用其方法

Emb*_*ise 4 java singleton multithreading design-patterns

在设计可供多个线程使用的单例类时,我遇到了以下挑战:

有一个主线程和另一个称为客户端的线程.主要方法首先获取一个实例,然后客户端也获取实例.然后客户端执行单例类的方法,我的调试步骤向我显示主线程被中断以执行客户端调用的方法.

如何确保客户端线程执行该方法,而不会中断主线程.

提前感谢您的努力.

干杯鲍勃

编辑:

public class SingletonEsperEngine {

    private static SingletonEsperEngine esperEngineObject;
    //Configuration for the Esper Engine
    private static Configuration cepConfig;
    //EPSServiceProvider represents the engine instance
    private static EPServiceProvider cep;
    private static EPRuntime cepRT;
    private static EPAdministrator cepAdm;
    private static boolean IsAlreadyInitialized;
    private static boolean IsNodeIdAvailable;
    public static ArrayList<EPStatement> cepStatement;
    public static ArrayList<EPStatement> cepLogInfo;
    public static ArrayList<EPStatement> cepFilterStatement;
    public static HashMap<String, Integer> mStatistics;
    public static HashMap<Integer, Integer> mNodeIds;


    //Experiment instantions
    private static JoinDebug joinDebugExperiment;



    private SingletonEsperEngine() {
    }

    /**
     * In order to prevent simultaneous invocation of the getter method
     * by 2 threads or more, we add the synchronized keyword to the method
     * declaration.
     *
     * @return SingletonEsperEngine
     */
    public static synchronized SingletonEsperEngine getInstance() {
        if (esperEngineObject == null) {
            esperEngineObject = new SingletonEsperEngine();
            IsAlreadyInitialized = false;
            IsNodeIdAvailable = false;
        }

        return esperEngineObject;
    }

    /**
     * InitEsperService
     *
     * Initialize the Esper Engine to accept MyriaNed messages.
     *
     * @return
     */
    public static synchronized int InitEsperService() {

    }

public int dataToEsperEngine(String data, int numOfClient) {
        //Split string into timestamp and Myrianed Message 32 bytes
        String strTimestampClientSec = data.substring(0, 16);
        String strTimestampClientNano = data.substring(16, 32);
        String strTimestampSniffer = data.substring(32, 40);
        String message = data.substring(40);
        String joinBitMask = CONSTANT.JOIN_MESSAGE_bm.substring(2, 4) + CONSTANT.JOIN_MESSAGE_bm.substring(0, 2);

        HashMap<String, Object> Event = new HashMap<String, Object>();

            //It is an join message

            Event = putDataIntoEvent(message, evaluationMsgStruct, stamp, numOfClient);
            cepRT.sendEvent(Event, CONSTANT.JOIN_MESSAGE)

        if (CONSTANT.DEBUG) {
            printEventHashMap(Event, evaluationMsgStruct);
        }

        return CONSTANT.SUCCESS;
    }
Run Code Online (Sandbox Code Playgroud)

客户端线程调用时会导致该问题 dataToEsperEngine()

public class Client implements Runnable {

    Socket mClientConnectionSocket;
    Connection mCon;
    //Seperate thread for every client, to handle the communication and event processing
    //ClientThread clientThread;
    public static Boolean stopClientThreads = false;
    public int mMode = CONSTANT.CLIENT_MODE_IDLE;
    public int mNumberOfThisClient;
    SingletonEsperEngine mEsperSupport;
    public Thread t;
    private String name;



    public void run() {
        String tmp = null;
        int idleTime = CONSTANT.SHORT_IDLE_TIME;

        while (!stopClientThreads) {
            try {
                tmp = null;
                switch (mMode) {
                    case CONSTANT.CLIENT_MODE_STOP:
                        //This will cause exiting of the while loop and terminates the thread
                        stopClientThreads = true;
                        return;
                    case CONSTANT.CLIENT_MODE_IDLE:
                        //Being lazy
                        break;
                    case CONSTANT.CLIENT_MODE_RECEIVE_STREAM:
                        tmp = receiveMessage();
                        if (tmp != null) {
                            System.out.println(tmp);
                            mEsperSupport.dataToEsperEngine(tmp, mNumberOfThisClient);
                        }
                        break;
                }

                //I am aware of the performance issues
                //TODO rebuild with execution pool
                this.t.sleep(idleTime);

            } catch (InterruptedException ex) {
                Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
            }

        }
        return;
    }

    Client(Socket cC, String name) {
        //Save socket (=connection) into the client class
        mClientConnectionSocket = cC;
        gui.Debug.logThis("The server made a connection with: " + mClientConnectionSocket.getInetAddress());

        mEsperSupport = mEsperSupport.getInstance();

        this.name = name;
        mMode = CONSTANT.CLIENT_MODE_IDLE;

        t = new Thread(this);
        t.start();

        this.mNumberOfThisClient = Integer.parseInt(name);

        //Connect the input and output stream
        try {
            mCon = new Connection(new BufferedReader(new InputStreamReader(mClientConnectionSocket.getInputStream())), new PrintWriter(mClientConnectionSocket.getOutputStream()));
        } catch (IOException ex) {
            Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
        }




    }

    public String receiveMessage() {
        String tmp = null;
        try {
            tmp = mCon.cFrom.readLine();
        } catch (IOException ex) {
            Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
        }

        return tmp;
    }
}
Run Code Online (Sandbox Code Playgroud)

Mic*_*fel 6

这与单身人士无关,是吗?您必须使用synchronized关键字来同步不会被中断的方法.这是一个难以回答的问题,有几本书(如Doug Lea'Java Concurrent Programming')你可以参考.除此之外,你的问题没有足够精确地说明我添加更多细节.