2016-08-13 44 views
0

我正在制作一个类似Skype的程序。我有一个“接受”线程和每个调用的多个用户线程。每次开始通话时,我都会将接受线程存储在数组列表中。我需要做的是当调用中少于两个人中断接受发送该命令的用户线程的接受线程时。为了在创建接受线程时做到这一点,我记录索引号并将其传递给所有用户线程,因此当它需要发送中断命令时,它只需使用索引号从数组列表中获取线程。但是,当我发送它没有任何反应。有人能告诉我这是为什么吗?先谢谢你!!!为什么我的线程在我中断时没有结束?

接收线程

import java.io.IOException; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.util.ArrayList; 

public class accept extends Thread { // Chat and Voice Server User Accept 
    private ServerSocket TextChat; 
    private Socket sText; 
    private int TextPort; 
    private int index; 
    boolean running = true; 

    accept(int ChatPort) { 
     TextPort = ChatPort; 
     chat.threads.add(this); 
     index = chat.threads.indexOf(Thread.currentThread()); 
     try { 
      TextChat = new ServerSocket(ChatPort); 
     } catch (IOException e) { 
      System.out.println("Cant create server on port "+ ChatPort); 
      try { 
       TextChat.close(); 
      } catch (IOException e1) { 
       e1.printStackTrace(); 
      } 
     } 
    } 
    public void run() { 
     while(running == true) { 
      try { 
       sText = TextChat.accept(); 
       System.out.println(sText+" Joined the chat"); 
       new TextChat(sText, TextPort, index).start(); 
      } catch (IOException e) { 
       System.out.println("Server on port "+TextChat+" Can't Accept"); 
       try { 
        TextChat.close(); 
       } catch (IOException e1) { 
        e1.printStackTrace(); 
       } 
      } 
     } 
     System.out.println("Server on port "+TextChat+" Is Shutting Down"); 
     try { 
      TextChat.close(); 
     } catch (IOException e1) { 
      e1.printStackTrace(); 
     } 
    } 
    public void setRunning(boolean run) { 
     running = run; 
    } 
} 

用户线程

import java.io.IOException; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.net.Socket; 
import java.util.ArrayList; 

public class TextChat extends Thread { 
    private ObjectOutputStream out; 
    private ObjectInputStream in; 
    private Socket s; 
    private String msg; 
    private Boolean running = true; 
    private int port; 
    private String name; 
private int threadIndex; 

TextChat(Socket sText, int TextPort, int index) { 
    s = sText; 
    port = TextPort; 
    threadIndex = index; 
    try { 
     out = new ObjectOutputStream(s.getOutputStream()); 
     if(port <= 65511) { 
      chat.users1.add(out); 
     }else { 
      chat.users2.add(out); 
     } 
     in = new ObjectInputStream(s.getInputStream()); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 
public void run() { 
    while(running == true) { 
     try { 
      msg = in.readObject().toString(); 
      String[] part = msg.split("/"); 
       if(part[0].equals("MYNAME")) { 
        name = part[1]; 
        System.out.println("NAME ADDED "+name); 
       } 
       if(!msg.equals(null)) { 
        if(port <= 65511) { 
         for(ObjectOutputStream o : chat.users1) { 
          o.writeObject(name+": "+msg); 
         } 
        }else { 
         for(ObjectOutputStream o : chat.users2) { 
          o.writeObject(name+": "+msg); 
         } 
        } 
       } 
      } catch (ClassNotFoundException | IOException e) { 
       System.out.println(name+" Disconneted from chat"); 
       if(port <= 65511) { 
        chat.users1.remove(out); 
       }else { 
        chat.users2.remove(out); 
       } 
       if(chat.users1.size() < 2) { 
        System.out.println("Chat server on port "+port+" is shutting down due to not enough people in call"); 
        chat.threads.get(threadIndex).running = false; 
        running = false; 
       } 
      } 
     } 
    } 
} 
+0

如果您很快就没有得到正确的答案,可以考虑通过创建一个小程序(最小的程序,我们可以编译和运行不变),然后测试和修改,以及向我们显示问题,[mcve]。 –

+0

我已经做了。我的问题是,我不能访问接受线程中的任何对象,我不能打断它。几个小时后,我一直在与它缠身。 – mardis7021

+0

不,你没有。请仔细检查您发布的内容,因为我们既不能编译也不能运行它 –

回答

2

当你中断一个线程,它所做的就是设置一个标志。这个标志被一些操作监视,但除非你正在使用这些操作之一,否则什么都不会发生。

如果你有一个在IO上被阻塞的线程,最有效的为什么解锁线程是关闭()流或套接字来杀死它。我还会设置一个标志,例如boolean closed,因此您可以检测到抛出的任何IOException是关闭套接字的原因,而不是错误。

编辑:一些建议。

  • 总是使用TitleCase作为类名。
  • 尽可能避免可变字段static字段。在这种情况下,我不相信你需要任何。
  • 总是通过共享状态,并确保它是线程安全的,从多个线程中使用。
  • 不要延长Thread而实现Runnable,并用它包装到一个Thread
  • 你只需要一个服务器端口在此情况下,除非你实现这是一个对等网络服务,但不似乎是这种情况。
  • while (running)需要时,无需编写像while (running == true)这样的详细表达式。
  • 如果您有线程间共享的boolean running请确保它是易失性的。
  • 不要发现异常并假装它没有发生。你最好在构造函数throws IOException而不是创建一个死对象。
  • 将每个客户端包装在一个对象中,只注册该对象,而不是运行该对象的线程。正如你所指出的,保持线程不是很有用。
  • 当您不期望null的值时,请勿使用像Boolean这样的包装。使用boolean而不是null
  • 我建议使用默认为false的标志。而不是running使用closed。这使得更容易知道变量的默认值/正常值是什么。
  • 不要在代码中硬编码这样的端口,你应该通过一个标志或一个id来说明它应该如何表现。
  • 只能使用对象流来传递一般对象。为了传递文本,您可以使用更简单的Writer/Reader或Data Stream。
  • 您不需要检查null的值,该值不能为nullmsg.equals(null)不能每回true
  • 在您的IDE中使用拼写检查程序Disconneted应该是Disconnected
  • 当有人可能要加入时,我不会断开连接。
+0

我无法访问线程中的任何对象。 – mardis7021

+0

@ mardis7021您可以访问该线程中的对象的线程。为什么你不能访问它中的任何对象?这是家庭作业的要求,还是你不知道怎么做? –

+0

@ mardis7021 BTW这个代码的结构有很多我会改变。 –

相关问题