Невозможно получить доступ и изменить одну и ту же переменную из двух потоков - PullRequest
0 голосов
/ 14 мая 2019

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

Вот код того, что я пробовал до сих пор. Проблема в том, как я создаю объект MyMessage в клиентах, или проблема в самом классе? (Может быть, даже четные, xD)

import groovy.transform.Synchronized

 class MyMessage {

     private def list = []

     private Object listLock = new Object[0]

     @Synchronized('listLock')
     void addChar(c) {
         list << c
     }

    @Synchronized('listLock')
     void clear() { 
        list = []
    }

    @Synchronized('listLock')
    Integer msgLength(){
        list.size()
    }

    @Synchronized('listLock')
    String getMessage(){
        list.join()
    }

 }
try {
    nick = args[2]
    final MySocket s = new MySocket(args[0], Integer.parseInt(args[1]))
    s.write(nick)
    //Output thread
    MyMessage msg_in = new MyMessage()

    def thIn = Thread.start {
        String msg_out
        while ((msg_out = s.readLine()) != null) {
            for(int i = 0; i < msg_in.msgLength(); ++i) System.out.print("\b")
            System.out.println("\r"+msg_out)
            System.out.print("You> "+msg_in.getMessage())
        }
        s.close()
    }

    def thOut = Thread.start {
        try{
                BufferedReader teclat = new BufferedReader(
                    new InputStreamReader(
                            System.in
                    )
                )
                char c
                while ((c = teclat.read()) != -1) {
                    // write msg to socket
                    if(c != "\n"){
                        msg_in.addChar(c)
                    }else if(msg_in.getMessage() == ""){
                        String seq = "" + (char) 27 + (char) 91 + (char) 65
                        System.out.print(seq)
                        System.out.print("\rYou> ")
                    }else{
                        s.write(msg_in.getMessage())
                        System.out.print("\rYou> ")
                        msg_in.clear()
                    }
                }
                s.close()
        }catch(IOException ex){
                System.out.println(ex.getMessage())
                System.exit(1)
        }
    }
    thIn.join();
    thOut.join();
} catch (NumberFormatException | InterruptedException ex) {
    System.out.println(ex.getMessage())
    System.exit(1)
}

В основном проблема заключается в том, что для thOut msg_in заполняется и фактически отправляет сообщения, но при перезаписи материала в консоли и последующей попытке записать его снова в th пустой msg_in (я полагаю, это не то же самое) экземпляр или еще что?)

...