Страницы

Поиск по вопросам

пятница, 27 декабря 2019 г.

Java шаблон Observer и многопоточность

#java #многопоточность #инспекция_кода #observer


Мне необходимо создать приложение, которое будет получать данные по сети и передавать
их другим классам для обработки. Я решила воспользоваться для этого шаблоном observer,
но столкнулась с проблемой. Одновременно может поступить несколько соединений, поэтому
для каждого я создаю новый экземпляр класса с принятием соединения и обработкой данных.
Но как тогда правильно привязать наблюдателей к классу сервера. Чтобы использовать
что-то в дополнительном потоке переменная должна быть статическая или финальная. Финальная
не подходит, потому что на каждое соединение новый экземпляр сервера. А статическая
меня смущает, я не совсем понимаю, как это работает. 

Внизу приведен код, подскажите, пожалуйста, как правильно это организовать, чтобы
во время эксплуатации никакая фигня не вылезла.

Это главный класс

public class Main {
    static Server server = new Server();

    public static void main(String[] args) {
    new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    int i = 0; // счётчик подключений
                    ServerSocket socket = new ServerSocket(3013);

                    while(true)// слушаем порт
                    {
                        server = new Server(i, socket.accept());
                        i++;
                    }
                }
                catch(Exception e){
                    System.out.println("init: " + e);                   
                }
            }
        }).start();

        ConcreteObserver observer = new ConcreteObserver(server);
    }
}


Это класс сервера

public class Server extends Thread implements Observable {
    Socket socket;
    int num;
    List string = null;

    private static List observers;

    public Server() {
        observers = new ArrayList();
    }

    public Server(int num, Socket s) {
        this.num = num;
        this.socket = s;
        start();
    }

    public void run() {
        // doing something
        notifyObservers();
    }

    public void addObserver(Observer o) {
         if (o != null) { 
             observers.add(o);
         }
    }

    public void deleteObserver(Observer o) {
        if (o != null) {
            observers.remove(o);
        }
    }

    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(listMettUnits);
        }
    }
}


И класс наблюдателя

public class ComputeAll implements Observer {
    private Server server =  null;

    public ComputeAll(Server server) {
        this.server = server;
        server.addObserver(this);
    }

    public void update(List list) {
        // doing something
    }
}

    


Ответы

Ответ 1



По данному коду у меня есть несколько замечаний. для observers не рекомендуется использовать LinkedList, лучше воспользоваться потокобезопасной реализацией, например java.util.concurrent.CopyOnWriteArrayList; регистрировать наблюдателей предпочтительнее до запуска сервера. Поля в классе Server и ComputeAll я бы сделал final Запуск потока в его конструкторе не очень хорошая идея, и вообще, явное создание потоков не есть хорошо, воспользуйтесь, как вариант, java.util.concurrent.ExecutorService И что касается не многопоточности, observers является статическим, что скорее всего не совсем верно.

Комментариев нет:

Отправить комментарий