Вопрос:
Я создал поток и назвал это нажатием кнопки:
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(); } } }
Мне нужно остановить поток после нажатия кнопки. Как я это сделаю? Я пробовал логические методы прерывания, но не работал. Как я могу остановить его? Пожалуйста, помогите мне.
Ответ №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() чтобы возобновить поток
Ответ №4private 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(); } });
Попробуй это.