notifyAll()无效,如何在socket编程中通知所有线程

时间:2016-05-11 07:17:34

标签: java multithreading sockets

所有线程都可以等待,但只通知1个线程(最后一个线程)。如何通知所有线程?

public class Server {   
static Socket clientSocket;
static int count = 0 ;
static boolean listeningSocket = true;

public static void main(String[] args) throws IOException {

    ServerSocket serverSocket = null;

    try {
        serverSocket = new ServerSocket(2343);
    } catch (IOException e) {
        System.err.println("Could not listen on port: 2343");
    }

    while(listeningSocket){
        clientSocket = serverSocket.accept();

        count++ ;
        Serverrun myThread[] = new Serverrun[3];
        myThread[count-1] = new Serverrun(clientSocket); 
        myThread[count-1].start();
        if(count>=3){
            listeningSocket = false;            
        }
    }
    serverSocket.close();       
}   

}

public class Serverrun extends Thread{

Socket clientSocket;

public Serverrun(Socket clientSocket) {

    this.clientSocket = clientSocket;
}

public void run(){

System.out.println("abc");
String clientSentence;
String cap_Sentence;
String rd1,rd2;

try {
    BufferedReader inFromClient = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
    DataOutputStream outToClient2 = new DataOutputStream(clientSocket.getOutputStream());
    outToClient2.writeBytes("User Login:"+'\n');        
    clientSentence = inFromClient.readLine();       
    System.out.println(" " +clientSentence+ "  : login");

} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    System.out.println("error");
}

    Server s = new Server();
    receivebj(s.listeningSocket);

    Game g = new Game();
    rd1=g.randomNum();
    rd2=g.randomNum();
    DataOutputStream outToClient;
    try {
        outToClient = new DataOutputStream(clientSocket.getOutputStream());
        outToClient.writeBytes(rd1+" "+rd2+'\n');
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

synchronized void receivebj(boolean listeningSocket){

        if(listeningSocket!=false){
            try {

                wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        System.out.println("work receivebj");
        notifyAll();

}   

}

我有3个客户 结果client1和client2未终止:

用户登录:ant

用户登录:bird

但是client3终止了:

用户登录:cat

卡数:9 Q

附加 类游戏

public class Game { 

String randomNum() {
    // TODO Auto-generated method stub

    String rd1,rd2;
    String[] names;
    names = new String[12];
    names[0] = "A";
    names[1] = "2";
    names[2] = "3";
    names[3] = "4";
    names[4] = "5";
    names[5] = "6";
    names[6] = "7";
    names[7] = "8";
    names[8] = "9";
    names[9] = "J";
    names[10] = "Q";
    names[11] = "K";
    int num = (int) (Math.random()*12);
    //System.out.println("Number:"+names[num]);
    return names[num];
}
}

班主任

class Client {
public static void main(String argv[]) throws Exception {
    String sentence;
    String modifiedSentence1,modifiedSentence2;


    BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
    Socket clientSocket = new Socket("localhost",2343);
    DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
    BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
    modifiedSentence1 = inFromServer.readLine();
    System.out.println(modifiedSentence1);
    sentence = inFromUser.readLine();       
    outToServer.writeBytes(sentence + '\n');

    modifiedSentence2 = inFromServer.readLine();
    System.out.println("Number of card:"+ modifiedSentence2);
    clientSocket.close();

}
}

结果服务器:

abc
 ant  : login
abc
 bird  : login
abc
 cat  : login
work receivebj method

1 个答案:

答案 0 :(得分:2)

您的多线程严重受损。您似乎误解了wait()notifyAll()的概念。这些不是在不同对象之间发送消息的消息传递系统。

Serverrun receivebj wait() notifyAll()同步。但是,你没有任何代码可以通过该对象上的Serverrun 将其唤醒。

因此,对于每个Serverrun,您只需挂起它的线程,并且永远不会将其唤醒。这不行。您需要拥有一个公共对象,以便wait()个实例执行strtotime("YYYY-MM-DD H:i:s")

我建议回到基础并多读一些多线程和并发,尤其是synchronization,因为你的错误是你误用了它。

相关问题