Как синхронизировать переменную в основной функции с новым потоком? - PullRequest
0 голосов
/ 11 марта 2020

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

public static void main(String[] args) throws Exception {
    // TODO code application logic here
    server = new ServerSocket(port);
    List<MySocket> sockets = new ArrayList<>();

    //this is thread responsible to synchronizing
    new SyncThread().start();
    while(true){
        Socket socket = server.accept();
        MySocket mySocket = new MySocket(socket);
        sockets.add(mySocket);
        SocketThread.setSockets(sockets);
        new SocketThread(mySocket).start();

    }
}

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

public class SyncThread extends Thread{
    private static List<MySocket> sockets;

    @Override
    public void run(){
        //send list sockets to client
    }
}

Как синхронизировать список сокетов между основной функцией и SyncThread?

1 Ответ

1 голос
/ 11 марта 2020

Сделайте ваш список синхронизированным списком:

List<MySocket> sockets = Collections.synchronizedList(new ArrayList<>());

И затем передайте это как параметр конструктора в SyncThread:

new SyncThread(sockets).start();  // Need to add constructor parameter to class.

public class SyncThread extends Thread{
    private final List<MySocket> sockets;  // NOT static.

    public SyncThread(List<MySocket> sockets) {
      this.sockets = sockets;
    }
    ...
}

Имейте в виду, что это не делает sockets синхронизировано для составных операций, например, итерации. Для этого вам нужно явно синхронизировать на sockets; или выберите другой тип списка, например CopyOnWriteArrayList, который по своей природе является поточно-ориентированным (выбор зависит от характеристик чтения / записи того, как вы используете список).

Кроме того, редко бывает целесообразно расширять Thread напрямую. Вместо этого передайте это Runnable:

new Thread(() -> { /* send list sockets to client */ }).start();
...