2012-06-09 5 views
0

У меня есть форма Swing с кнопкой, которая при нажатии начинается с SocketServer для прослушивания входящих запросов в отдельном потоке. Ниже приведена структура классов, которые у меня есть.Завершение выполнения Thread без использования метода stop()

  • MainForm: Это мой основной класс, который запускает Swing Form. Он имеет две кнопки: «запустить сервер» и «кнопки остановки».
  • MySocketServer: Этот класс является таким, где SocketServer объект существует, он имеет методы startServer() и stopServer().

следующее: Нажмите кнопку «Показать событие».

t = new Thread(new Runnable() //Object t is created globally in this main class. 
{ 
    public void run() 
    { 
     myss = new MySocketServer(); //Object myss has similar accessibility as t. 
     myss.startServer(); 
    } 
}); 
t.start(); 

И Ниже Стоп Нажмите на событие Body

myss.stopServer(); 
if(t.isAlive()); 
    System.out.println("Thread is still alive!!"); 

Хотя я могу переключить SockeServer «старт» и «стоп» в мое время, я хочу, но я понимаю, что каждый раз я начинаю сервер, новый поток создается и остается активным, даже если сервер остановлен с использованием метода MySocketServer.

я могу использовать stop() из Thread и остановить выполнение нити, но так как она амортизируется, и я изучал, что нити получают закончились, как только их метод run() выполнил полностью, но я startServer() метода разделен таким образом, что он может работать с подключенными клиентами отдельно ,

Пожалуйста, обратите внимание, что startServer() имеет While-Listen петли, так что по существу run() метод резьбы в бесконечном состоянии исполнения, пока явно не вызовет stopServer() и остановить цикл.

что можно сделать здесь?

ответ

0

В вашем классе MySocketServer в цикле while вам нужен флаг, который будет проверять, должен ли он работать или нет.

В вашем недавно добавленном способе выключения установите флаг, который будет проверять цикл в потоке. Как только цикл прерывается и запускается(), поток завершается.

+0

У меня есть булевский флаг, который используется в методе 'serverStart()', который проверяется на каждой итерации цикла, и я устанавливаю этот флаг в false в 'startServer()', в то время как отладка теперь я узнал, что while цикл заканчивается при вызове 'stopServer()', и даже метод 'run()' потока завершает свое выполнение элегантно, но почему я получаю 'isAlive()' true, даже если запуск завершен? – Kushal

0

Вы не должны использовать stop(). Взгляните на это http://docs.oracle.com/javase/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html Решение с бесконечными циклами цикла и начала/остановки является простым, но приводит к неэффективному использованию времени процессора. Лучший способ - использовать метод wait/notify. То, как вы работаете с MySocketServer, дает мне ощущение, что у вас есть другой бесконечный цикл внутри startServer(). Вот почему вы должны остановить это. Было бы лучше обернуть этот цикл в собственный поток внутри и заставить методы start/stop работать с этим состоянием потока в ожидании/уведомлении. Вспомните, поскольку ваш графический интерфейс работает в своем потоке, вы не можете избежать флага начала/остановки внутри MySocketServer, потому что использование wait() в потоке графического интерфейса сделает его повешенным.

2

Во-первых, вы правы, чтобы не пытаться использовать Thread.stop(). Это потенциально опасно.

Так что вы должны делать?

Одним из возможных вариантов может быть, чтобы написать нить сервера, как это:

.... 
    ServerSocket ss = new ServerSocket(...); 
    try { 
     while (keepGoing) { 
      Socket s = ss.accept(...); 
      try { 
       // do stuff 
      } finally { 
       // close socket 
      } 
     } 
    } finally { 
     // close the server socket 
    } 

и имеют stopServer ясно, что keepGoing флаг. Но проблема в том, что остановка обычно придет, когда поток заблокирован в вызове accept, и нет ничего, чтобы разблокировать его.

Другая возможность может заключаться в том, чтобы позвонить Thread.interrupt() по теме. Это заставляет некоторые вещи разблокировать и выдавать исключение, но я не думаю, что он разблокирует вызов accept(). (Тем не менее, это по-прежнему лучше, чем установка флага, если часть «do stuff» требует прерывания.)

Настоящим решением (я думаю) является закрытие ServerSocket. Это вызовет вызов ss.accept(), чтобы разблокировать и выбросить исключение, которое необходимо обрабатывать в потоке сервера.

+0

, поскольку вы предложили закрыть «ServerSocket», я уже выполняю оба метода «stopServer()» основного класса, закрывая ServerSocket и устанавливая флаг boolean как false, который в конечном итоге закончит цикл. Поэтому я считаю, что метод 'run()' фактически заканчивает выполнение, но все же я получаю 'isAlive()' true для потока. – Kushal

+0

установите условие while в приведенном выше коде на:! ss.isClosed() Затем, если вы просто вызываете ss.close() из любого метода, чтобы закрыть сервер, метод accept будет разблокировать и выбросить исключение SocketException, которое вы должны безопасно поймать и проигнорировать, проверив ss .isClosed() в вашем блоке catch. – Matt

Смежные вопросы