无法从两个线程访问和修改相同的变量

时间:2019-05-14 11:27:33

标签: groovy concurrency locking synchronized

我正在用Groovy做一个基于控制台的简单聊天应用程序。以前,我已经完成了有关Java并发的更复杂的工作,但是即使现在最简单的事情也使我花了很多时间,而且我不知道错误在哪里(我对groovy真的很陌生)。我希望能够以一种简单的方式从两个不同的线程中写入和读取字符串或字符列表(消息),而我陷入困境(我保持findind许多不同的选择,并且感到困惑)。 我不允许使用其他库,因此目前不允许使用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)
}

基本上,问题在于这样的事实,即msg_in已填充并实际发送消息,但是当在控制台中覆盖内容然后尝试再次在其中写入时,msg_in为空(我猜是不一样的)实例还是其他?)

0 个答案:

没有答案