【问题标题】:Stop thread after button click单击按钮后停止线程
【发布时间】:2014-03-19 09:22:44
【问题描述】:

我创建了一个线程并在单击按钮时调用它:

btnUpload.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
         new Thread(new ClientThread()).start();
    }
});

这是我的主线:

class ClientThread implements Runnable {

        @Override
        public void run() {

            try {
                InetAddress serverAddr = InetAddress.getByName(SERVER_IP);

                socket = new Socket(serverAddr, SERVERPORT);

            } catch (UnknownHostException e1) {
                e1.printStackTrace();

            } catch (IOException e1) {
                e1.printStackTrace();

            }

        }

    }

我需要在按钮单击操作后停止线程。我将如何做?我尝试过布尔,中断方法但不起作用。我怎样才能阻止它?请帮帮我。

【问题讨论】:

  • 线程在其运行方法结束时结束其生命周期。
  • 您可以参考stackoverflow.com/questions/22166832/…希望对您有所帮助。
  • 可能通过停止线程,您的意思是关闭在run() 中创建的套接字?
  • 是的@mangusta,你是对的。但是怎么做呢?
  • @androidsuckzzz 使该套接字成为ClientThread 的实例变量,并在必要时放置一些修改器方法来关闭它,或者通过直接从ClientThread 对象调用来关闭它

标签: java android


【解决方案1】:

试试这个测试代码:

public class Test3 {
    public static void main(String[] args) throws InterruptedException, IOException {
        Thread serverThread = new Thread(new ServerThread());
        serverThread.start();

        ClientThread client = new ClientThread();
        Thread clientThread = new Thread(client);
        clientThread.start();
        Thread.sleep(5000);
        client.closeSocket();
    }
}

class ServerThread implements Runnable {
    @Override
    public void run() {
        try {
            ServerSocket serverSocket = new ServerSocket(7777);
            serverSocket.accept();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

class ClientThread implements Runnable {
    Socket socket;

    public void closeSocket() throws IOException {
        socket.close();
    }

    @Override
    public void run() {
        try {
            InetAddress serverAddr = InetAddress.getByName("127.0.0.1");
            socket = new Socket(serverAddr, 7777);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

这会成功关闭套接字并退出线程。

【讨论】:

    【解决方案2】:

    我猜你想要做的是启动套接字,然后等待一些事件(例如按钮单击)然后停止它。您可以使用受保护的块来等待标志。

    您的课程将如下所示

    class ClientThread implements Runnable {
    
        private static final int SERVERPORT = 0;
        private static final String SERVER_IP = null;
        Socket socket;
        boolean stopFlag;
    
        public ClientThread(){
            stopFlag = false;
        }
    
        public void setStopFlag(){
            stopFlag = true;
        }
    
        @Override
        public void run() {
    
            try {
                InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
                socket = new Socket(serverAddr, SERVERPORT);
                synchronized(this){
                    while(!stopFlag){
                        try {
                            wait();
                        } catch (InterruptedException e) {}
                    }
                }
                socket.close();
    
            } catch (UnknownHostException e1) {
                e1.printStackTrace();
    
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
    
    }
    

    当您启动 clientThread 时,请持有该实例以便稍后发出信号。

    ClientThread ct = new ClientThread();
    new Thread(ct).start();
    

    当您想停止套接字时(例如,通过单击按钮),请执行此操作

    synchronized(ct){
       ct.setStopFlag();
       ct.notifyAll();
    }
    

    更多关于受保护块的信息可以在这里找到 - http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html

    我推荐你阅读整个java并发教程-http://docs.oracle.com/javase/tutorial/essential/concurrency/index.html

    并发是一个非常有趣且具有挑战性的话题。启动线程的语法可能很简单,但不要让它误导你。

    【讨论】:

      【解决方案3】:

      只要单击按钮或发生事件(只要您愿意),就在线程上调用 wait() 方法,然后再次调用 notify() 方法以恢复线程

      【讨论】:

      • 你能解释一下吗?这些方法都是在多线程的情况下使用的!
      • 我建议你在使用Thread类方法的API之前先阅读它们。
      • 多线程??是的。并且供您参考,主要方法也是一个线程。所以当你创建另一个线程时,你不是有多个线程吗???先了解线程概念,然后再使用它们。
      【解决方案4】:
      private Thread thread = new Thread(new ClientThread());
      private boolean isStarted = false;
      btnUpload.setOnClickListener(new View.OnClickListener() {
      
              @Override
              public void onClick(View v) {
                  if (!isStarted)
                      thread.start();
                  else
                      thread.stop();
          }
      });
      

      试试这个。

      【讨论】:

      • 这个不行,这是贬值了。
      猜你喜欢
      • 1970-01-01
      • 2012-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多