服务器代码部分内容如下:
Message是一个类,类里面有private int IDFrom;
                private int IDTo;
                private int type;
                private Object Content;
type是判断我服务器收到的内容是一个命令还是消息,命令有登陆,传文件等。
首先,我们收到一个Message,它让一个客户登陆了。
接着发送了一个消息,消息到达了服务器,放在了服务器的一个临界区里,是linkedlist型的。
另一个客户也登陆了,要接收这个消息。
于是就接收不到了。
经过反复研究,发现它是卡在了if((objMsg = ins.readObject())!= null  )。
要有第二条消息发送过来,它才能接收前一条。
这样消息就不仅仅是延迟了。
请问该怎么解决这个问题。。
抱拳感谢!!!package try1;
import java.io.*;import java.net.*;
import java.io.*;
import java.util.*;public class Server implements  Serializable{
public static void main(String[] args) throws IOException 
{
Thread thread = new Thread()
{
private ServerSocket server;
private int threadID = 0;
public void run()
{
try
{
System.out.println("================服务器已启动================");
server = new ServerSocket(8888);
while(true)
{
Socket client = server.accept();
//输出提示
System.out.println("有新的连接......"+client.getInetAddress());
threadID ++;
ServerThread clientthread = new ServerThread(client,threadID);
clientthread.start();
}
}
catch(IOException ex)
{

}
}
};
thread.start();
}
}class ServerThread extends Thread{
 private Socket netClient;
 private int threadID;
 private static LinkedList[] msgList = new LinkedList[100];
 private static HashMap<Integer ,Integer> threadMap = new HashMap<Integer,Integer>();
 
 
 public ServerThread(Socket client,int threadID) throws IOException
 {
 this.netClient = client;
 this.threadID = threadID;
 msgList[threadID] = new LinkedList();
 }
 //--------------------------------------
 //读取各线程接收的消息列表
 //--------------------------------------
 public synchronized Object ReadMsg(int threadid)
 {
 return(msgList[threadid].remove());
 }
 public synchronized boolean WriteMsg(int threadid,Object msg)
 {
 return(msgList[threadid].add(msg));
 }
 //---------------------------------------
 //读取当前线程获得消息的来源
 //---------------------------------------
 public synchronized int ReadThreadID(int userid)
 {
 //return threadMap.get(userid);
 if(threadMap.containsKey(userid))
 return threadMap.get(userid);
 else
 return 0;
 }
 public synchronized void WriteUserID(int userid,int threadid)
 {
threadMap.put(userid,threadid);
 }
 
 public void run()
 {
//输出提示
 System.out.println(netClient.getInetAddress()+"客户服务线程"+threadID+"已启动...");
 
 try
 {
 ObjectOutputStream outs = new ObjectOutputStream(netClient.getOutputStream());
 ObjectInputStream ins = new ObjectInputStream(netClient.getInputStream());
 Object objMsg;
 while(true)
 {
 if((objMsg = ins.readObject())!= null  )//!!!!!!!!!!!!!卡在了里!!!!!
 {

 Message msg = (Message)objMsg;
 System.out.println("命令类型:"+msg.getType());
 switch(msg.getType())
 {
 case 1://表示用户发送消息命令    
 int threadid = ReadThreadID(msg.getIDTo());
 if(threadid != 0)//当线程ID=0时表示该信息是发送给服务器的
 WriteMsg(threadid,objMsg);
 
 
 break;
 case 3://表示用户登录时注册命令
 //提示信息
 System.out.println("注册用户:"+msg.getIDFrom());
 
 WriteUserID(msg.getIDFrom(),threadID);
 
 System.out.println("该用户的线程号:" +ReadThreadID(msg.getIDFrom()));
 //-----------------------------------
 //其余登陆需要的操作
 //-----------------------------------
 break;
 case 7:
 
 break;
 
 }
 }
 if( !msgList[threadID].isEmpty())
 {
 outs.writeObject(ReadMsg(threadID));
 }
 }  
 }
 catch(IOException ex)
 {
 
 } catch (ClassNotFoundException e) 
 {
// TODO Auto-generated catch block
e.printStackTrace();
 }  
 }
}

解决方案 »

  1.   

    没格式化的代码看不下去flush了没有?
      

  2.   

    readObject()阻塞是很正常的,除了1楼说的要在对方经常flush之外,
    楼主不妨将下面的那个if( !msgList[threadID].isEmpty())改成while( !msgList[threadID].isEmpty()),会好一些。
      

  3.   

    不过还是有一个问题,flush()处理的不是输出流的问题么?可是现在我们是卡在了In里边。flush固然能优化,貌似还是不能解决根本问题啊。
    是这样,我们要接受的消息存放在了临界区,当外界没有继续给我们东西的时候,我们的INPUT是空的,于是程序卡在了readObject()等待下一条消息的来临。可是我们现在要从临界区里拿之前存放在里边属于我们的东西了,就拿不到了。那么该怎么办。
      

  4.   

    是这个问题。
    要么在read前拿临界区的东西。
    要么多线程,read归read一个线程,拿归拿一个线程,互不影响。