1

所以我试图实现一个多线程的java代码来模拟一个消息服务器和客户端。他们共享一个共同的资源进行交流。客户端应该只有在服务器通知它并从用户接收到消息后才能读取消息。这种情况一直持续到用户键入“退出”。

现在,下面的代码工作得很好:

import java.util.Scanner;

class Message{
    Scanner sc = new Scanner(System.in);
    private String text="";
    private boolean hasText;

    public void writeText(){
        while(hasText)
            try{
                wait();
            }catch (InterruptedException e){ System.out.println(e.toString()); }
        hasText = true;
        System.out.print("Server wants you to enter a message: ");
        text = sc.nextLine();
        System.out.println("Server wrote the message: " + text);
        notify();
    }

    public void readText(){
        while(!hasText)
            try{
                wait();
            }catch(InterruptedException e){System.out.println(e.toString());}
        System.out.println("Client read the current message: " + text);
        System.out.println("------------------------------");
        hasText = false;
        notify();
    }

    public String getText(){
        return text;
    }
}

class Server extends Thread{
    final Message m;
    Server(Message m){
        this.m = m;
    }
    public void run(){
        synchronized(m) {
            while (!m.getText().equals("quit"))
                m.writeText();
        }
    }
}

class Client extends Thread{
    final Message m;
    Client(Message m){
        this.m = m;
    }
    public void run(){
        synchronized (m) {
            while (!m.getText().equals("quit"))
                m.readText();
        }
    }
}

class B{
    public static void main(String[] args){
        Message m = new Message();
        new Server(m).start();
        new Client(m).start();
    }
}

输出:

Server wants you to enter a message: lol 
Server wrote the message: lol 
Client read the current message: lol 
------------------------------ 
Server wants you to enter a message: gg 
Server wrote the message: gg 
Client read the current message: gg 
------------------------------ 
Server wants you to enter a message: quit 
Server wrote the message: quit 
Client read the current message: quit 
------------------------------

但是,当我尝试直接从 Server 和 Client 类实现函数writeText()readText()时,如下所示:

import java.util.Scanner;

class Message1{
    public String text="";
    public boolean hasText;
}

class Server1 extends Thread{
    Message1 m;
    Server1(Message1 m){
        this.m = m;
    }
    public void run(){
        synchronized(m) {
            while (!m.text.equals("quit")){
                while(m.hasText)
                    try{
                        wait();
                    }catch (InterruptedException e){ System.out.println(e.toString()); }
                m.hasText = true;
                System.out.print("Server wants you to enter a message: ");
                Scanner sc = new Scanner(System.in);
                m.text = sc.nextLine();
                System.out.println("Server wrote the message: " + m.text);
                notify();
            }
        }
    }
}

class Client1 extends Thread{
    Message1 m;
    Client1(Message1 m){
        this.m = m;
    }
    public void run(){
        synchronized (m) {
            while (!m.text.equals("quit")) {
                while(!m.hasText)
                    try{
                        wait();
                    }catch(InterruptedException e){System.out.println(e.toString());}
                System.out.println("Client read the current message: " + m.text);
                System.out.println("------------------------------");
                m.hasText = false;
                notify();
            }
        }
    }
}

class B1{
    public static void main(String[] args){
        Message1 m1 = new Message1();
        new Server1(m1).start();
        new Client1(m1).start();
    }
}

它引发了 IllegalMonitorStateException。

我非常想知道为什么。啊。感谢帮助:))

ps,我还更改了我的消息类的文本和标志的访问修饰符,以避免使用 getter 和 setter。

4

0 回答 0