【问题标题】:Communication between parent and child thread in JavaJava中父子线程之间的通信
【发布时间】:2013-04-30 04:02:14
【问题描述】:

我有一个主线程,并在该线程中启动一个新线程。 (子线程)。该子线程打开一个服务器套接字并开始监听连接。 我希望该线程在主线程从外部获取消息时停止执行并关闭它已初始化的任何内容(如套接字)(不关心从哪里获取消息)。我应该如何停止线程并关闭所有连接是我想要的。

我应该使用共享变量吗?这样当主线程收到消息时,它应该修改它,而子线程应该不断检查该共享变量的变化?

我应该如何实现它?一些有用的链接可能会有所帮助或示例代码?

我尝试过的如下: 在主线程中我声明了一个变量

 flag=0;

主线程收到消息后,设置

flag = 1 ;

线程监听变化如下:

  void ()run{

       while(true){

            if(flag==1){
                   break;
              }

       sock1 = Ssocket.accept(); 
  }

但是上面的代码根本不起作用。我该怎么做?

【问题讨论】:

  • 我会尽力回复您...但是我的代码有什么问题?
  • 标志只为你的父线程改变,子线程仍然认为它是“0”
  • 使标志易变。 private volatile int flag;.
  • 如果你们中的任何人都可以解决有关 android-bluetooth 的问题,请帮我检查一下stackoverflow.com/questions/16413498/…

标签: java multithreading sockets


【解决方案1】:

中断线程的正确方法是通过中断机制。在你的主线程中,当你想停止子线程时,你调用:

childTread.interrupt();

在子线程中,您可以执行以下操作:

public void run() {
    try {
        while (!Thread.currentThread.isInterrupted) {
            sock1 = Ssocket.accept();
            //rest of the code here
        }
    } catch (InterruptedException e) {
        Thread.currentThread.interrupt(); //good practice
    }
    //cleanup code here: close sockets etc.
}

注意Ssocket.accept 是不可中断的,所以如果你想阻止它等待,你必须从外面关闭它,强制它抛出一个IOException

【讨论】:

  • 我应该如何从外面关闭它?只有我的子线程知道套接字.....还是我应该在子线程之外的某个地方声明它?在主线程中?
  • 您可以在您的子线程中提供一个closeSocket 方法来关闭套接字(并使accept 抛出异常)。当然,您需要从不同的线程调用它。
  • 你能不能通过这个问题看看你能不能解决这个问题??它在 android -bluetooth stackoverflow.com/questions/16413498/…
  • @user2354443 我从来没有使用过蓝牙连接,所以帮不上什么忙。
【解决方案2】:

Child thread

你应该在这里创建一个新函数,f.e:

public void setFlag(int i)
  {
     flag = i;
  }

Parent Thread

每当您想在子线程中终止/停止侦听/...时,请调用:

 childThread.setFlag(1);

如果您不需要子线程是匿名的,请创建一个 ChildThread

 public ChildThread implements Runnable
{
    private int flag = 0;

    public ChildThread()
     {  }

    public void setFlag(int i)
      {
         flag = i;
      }
    public void run()
      { 
       //your code
      }
    ....
}

【讨论】:

  • 我无法从主线程调用 childThread.setFlag(1) .....它显示了一些错误。
  • 更改“childThread”为您的实际子线程的名称; )
  • t.setFlag(1),并且在线程中我有 public void setFlag(int i){ flag = i }
  • 这里没有聊天吗?这样我就可以将整个代码发布给你
  • 您是否定义了更多具有相同名称的类?重命名您的 .java。另外,请先尝试清理您的项目。您的课程名称似乎有问题..
【解决方案3】:

如果您使用标志来指示线程停止,请确保读/写访问是同步的。例如:


   public synchronized void cancel ()
   {
       stop = true;
   }

   protected synchronized boolean cancelRequested ()
   {
       return stop;
   }

【讨论】:

【解决方案4】:

用您自己的实现扩展Runnable

public class StoppableRunnable extends Runnable {

}

编写你的类,这样你就可以停止Runnable的执行,你会在How to properly stop the Thread in Java?找到一个很好的例子来说明如何做到这一点。请务必查看前两个答案

在您等效的 terminate() 函数中,进行所有清理

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-19
    • 2011-04-13
    • 1970-01-01
    • 2015-08-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多