синглтон поток - PullRequest
       18

синглтон поток

0 голосов
/ 11 февраля 2011

Хорошо, вот моя проблема.

Мне нужно создать программу-сокет, которая может обрабатывать несколько подключений из моих клиентских приложений (назовем это apps1).Я обрабатываю это с помощью потока (поэтому каждое соединение было брошено в новый поток)

Проблема в том, что я могу принять запрос от всех открытых соединений, но когда я хочу отправить ответ, я должен отправить его через последнее соединениетолько.Поэтому, если у меня есть 3 соединения (con1, con2, con3), я могу принять запрос от con1, con2 и con3, но я должен отправить ответ через con3 (при условии, что con3 - последнее соединение)

Я подумал об использованиисинглтон с параметром PrintWriter.Поэтому при каждом новом подключении они вызывают синглтон и обновляют параметр, а когда я хочу отправить ответ, я сначала получаю PrintWriter перед отправкой.

Вот мой класс Singleton:

public class Singleton {

private static final Singleton instance = new Singleton();

PrintWriter  out;

public static Singleton getInstance() {
    return instance;
}
public Singleton ()
{
    if (instance != null) {
        throw new IllegalStateException("Already instantiated");
    }
}

public PrintWriter getPrintWriter ()
{
    return this.out;
}
public void updatePrintWriter (PrintWriter  out){
    this.out = out;
}
}

Это моя основная программа:

public class SocketAccept{
private ServerSocket mainSocket;
private Socket clientSocket;

    public SocketAccept (int portNumber) {
        Singleton s = Singleton.getInstance();
        do {
        try {
            mainSocket = new ServerSocket(portNumber);
            clientSocket = mainSocket.accept();
            s.updatePrintWriter(new PrintWriter(clientSocket.getOutputStream(), true));
            ClientThread (clientSocket);
        } catch (IOException ex) {
            Logger.getLogger(TestClass.class.getName()).log(Level.SEVERE, null, ex);
        }
        }while (true);//need to change this into thread pool or connection pool    
    } 
}

и это мой поток, который обрабатывает сокет:

public class ClientThread extends Thread {

    private Socket cs;
    Singleton s = Singleton.getInstance();
    PrintWriter out;

    private String read(Socket sc) {
        String request = "";
        //read request here
        return request;
    }

    private String process(String request) {
        String response = "";
        //process request here
        return response;
    }

    public ClientThread(Socket clientSocket) {
        this.cs = clientSocket;
    }

    @Override
    public void run() {
        String requestMsg = "";
        String responseMsg = "";
        do {
            requestMsg = read(cs);// read the message

            if (requestMsg.equalsIgnoreCase("SHUTDOWN")) {
                break;
            }
            responseMsg = process(requestMsg);
            out = s.getPrintWriter();
            out.write(responseMsg);
        } while (true);
    }
}

Я правильно сделал?Или это невозможно сделать с помощью синглтона?

Спасибо за помощь.

1 Ответ

3 голосов
/ 11 февраля 2011

К сожалению, это не потокобезопасная реализация шаблона Singleton.Я не думаю, что он вам нужен в этом случае, AtomicReference , вероятно, будет работать нормально.Попробуйте это:

public class SocketAccept{
    private ServerSocket mainSocket;
    private Socket clientSocket;

    private final AtomicReference<PrintWriter> printWriterHolder = new AtomicReference(null);

    public SocketAccept (int portNumber) {
        Singleton s = Singleton.getInstance();
        do {
        try {
            mainSocket = new ServerSocket(portNumber);
            clientSocket = mainSocket.accept();
            printWriterHolder.set(new PrintWriter(clientSocket.getOutputStream(), true));
            Thread clientThread = new ClientThread (clientSocket, printWriterHolder);
            clientThread.start();
        } catch (IOException ex) {
            Logger.getLogger(TestClass.class.getName()).log(Level.SEVERE, null, ex);
        }
        }while (true);//need to change this into thread pool or connection pool    
    } 
}

...

public class ClientThread extends Thread
    ...
    private final AtomicReference<PrintWriter> printWriterHolder;
    public ClientThread(Socket clientSocket, AtomicReference<PrintWriter> holder) {
        this.cs = clientSocket;
        this.printWriterHolder = holder;
    }

    @Override
    public void run() {
        String requestMsg = "";
        String responseMsg = "";
        do {
            requestMsg = read(cs);// read the message

            if (requestMsg.equalsIgnoreCase("SHUTDOWN")) {
                break;
            }
            responseMsg = process(requestMsg);
            out = printWriterHolder.get();
            out.write(responseMsg);
        } while (true);
    }
}

Если вы действительно хотите использовать шаблон Singleton, вот ссылка из SO, где вопрос имеет хороший потокобезопасныйреализация для создания Singleton: Java Singleton Pattern

Вам также потребуется сделать доступ к потоку Singleton безопасным с помощью synchronized, Lock или атомарных операций (AtomicInteger, AtomicReference и т. Д.) По мере необходимости.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...