Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > остановка потока


Автор: barin_Student 24.4.2008, 13:49
Все что нашел в поисковике , и все что висит внизу темы , я читал , и пробывал.. но есть одно ,но это все одно и тоже , но у меня не выходит..
Какими способами можно убить поток, исключая:
переменную , которая говорит о том что пора выходить из цикла run()?
Могу привести строки своего потока , если он потребуется, кто может пояснить , почему после stop()(знаю что так не хорошо останавливать потоки), не запускаеться поток таким вот видом:
Код

ThreadClass t = new ThreadClass();
t.setDaemon(true);
t.start();
t.stop();
Thread t = new Thread();
t.setDaemon(true);
t.start();

 smile 

Автор: ivg 24.4.2008, 14:01
Цитата(barin_Student @  24.4.2008,  13:49 Найти цитируемый пост)
переменную , которая говорит о том что пора выходить из цикла run()?

А чем не устраивает?
Цитата(barin_Student @  24.4.2008,  13:49 Найти цитируемый пост)
не запускаеться поток таким вот видом

Метод run() класса java.lang.Thread пустой, я думаю он запускается и ничего не делая, останавливается.

Автор: barin_Student 24.4.2008, 14:06
Да на том примере что я привел - он пустой, но у меня на чтение данных порой поток вешаеться , и если я выставлю переменную , толку будет?
Вот моя задачка , как реализованна, вот на ней можно будет поиграцца:
Код

   public void run()
   {
        int i = 1;
        sim.TerminalStatus="Inicialize......";
        this.Inicialization();
        sim.TerminalStatus="Set settings....";
        this.setAllSettingsOnStart();// повиснуть может и здесь
       while(true)
        {
            try
            {
                sim.TerminalStatus="Status ok.......";
                if(sim.TerminalQueue.isEmpty()==false)
                {
                     PDU pdu =sim.TerminalQueue.take();
                     if(pdu.getCommandId()==Data.SUBMIT_SM)
                    {
                        SubmitSM submit = new SubmitSM();
                        submit.setBody(pdu.getBody());
                        String telephone = submit.getDestAddr().getAddress();
                        telephone = telephone.substring(1,telephone.length());
                        String text = submit.getShortMessage();
                        Time= new GetCurrentTime();
                        sim.TerminalLastTime=Time.getTime();
                        this.sendSMS(telephone,text);// повиснуть может и здесь
                     }
                }
                this.waiter();
                if(i>=20)
                {
                     this.listMessages();// повиснуть может и здесь
                     this.gsmReader.DeleteMessagesFromMessageStore();// повиснуть может и здесь
                     i=1;
                }
                i++;
            }
            catch(Exception e)
            {
                errorWriter = new ErrorWriter();
                errorWriter.WriteError("Error in RUN in GSMModem  "+e);
            }
        }
    }
}


Автор: Kangaroo 24.4.2008, 14:12
Цитата(barin_Student @  24.4.2008,  14:06 Найти цитируемый пост)
чтение данных порой поток вешаеться , и если я выставлю переменную , толку будет?

Читаешь данные, проверяешь переменнею, опять читаешь, проверяешь переменненую.........

Автор: ivg 24.4.2008, 14:16
можно ещё поэкспериментировать с interrupt();
А что значит повиснуть? Несанкционированное повисание потока - это баг, надо его лечить. Если имеется ввиду блокирование потока в ожидании завершения IO операций, то в таких случаях предусматривают таймауты.

Автор: barin_Student 24.4.2008, 14:16


Код

Читаешь данные, проверяешь переменнею, опять читаешь, проверяешь переменненую......... 

Если так:
Код

public void quit()
{
     quit=true;
}
public void run()
{
     while(quit==false)
      {
             while(true)
             {
             }
       }
}



Автор: SoulKeeper 24.4.2008, 14:44
Тогда уже:

Код

public void run(){
while(!quit){
... код чтения тут...
}
}

Автор: Бонифаций 24.4.2008, 14:47
если зависает где то на чтении - не поможет.. А вообще трассировку делали? где виснет то?

Автор: barin_Student 24.4.2008, 14:48
Код

public void run(){
while(!quit){
   while((String s =r.readline())!=null)//  .. код чтения тут..., а если r.readline никогда не станет null , как мне остановить такой поток?
    {
     }
}
}


Добавлено через 2 минуты и 20 секунд
Код

если зависает где то на чтении - не поможет.. А вообще трассировку делали? где виснет то? 

по своему примеру , я могу еще добавить один класс , и указать где , и могу сказать почему виснет. Если надо , то могу запостить. 
Это паралельный вопрос , но основной , - это как мне остановить поток при такой ситуации? 

Автор: barin_Student 25.4.2008, 05:31
Ниужели нельзя stop()  , а далее заново запустить? С критическими данными этот поток не работает.

Автор: Vurn 25.4.2008, 06:48
Автору - для этого существует два метода.
Первый - Socket.setSoTimeout(time);
Сокет держится в read только указанное время, если данные не получены - выходит с длиной 0, и можно по циклу проверть.

Второй Thread.interrupt(); 
Он рвет состояния чтения указанной нити. read тоже выходит из режима ожидания с длиной 0.

Автор: barin_Student 25.4.2008, 07:00
Счас проверю и посмотрю, но ведь не всегда поток на чтение зависает , , и  у меня не сокет , а ком порт., но все равно посмотрю.

Автор: le_chat 25.4.2008, 11:06
Была подобная проблема. 

Вариант с  Thread.interrupt() я не рассматривал, ибо вроде как по описанию при блокирующем вводе-выводе он не поможет. Для se - io операция будет прервана только nio пакета. Есть конечно шанс что внутри реализации, скажем, блокирующего чтения поток вести на wait'е, тогда конечно все должно сработать. 

Для me nio вообще не предусмотренно, поэтому все решалось закрытием читающего стрима из внешнего трэда. Его вставлял в shouldStop() и закрывал после установки стоп-флага потока. 
Тогда read() переставал ждать данные и возвращал -1, и run() нормально завершался по стоп флагу.

Могу предложить менее красивый и более ограниченный вариат: выставить для читающего потока setDemon(true). Это возможно и не решит проблемы с высвобождением ресурсов, но позволит завершить родительский поток (другими словами - позволит завершить приложение даже если читающий поток не завершился. jvm тоже завершится. Поэтому возможно ресурсы и будут высвобождены). smile

Автор: barin_Student 25.4.2008, 11:17
Поток у меня итак демон, и хорошо что он основной тред не останавливает..
Скажем я поток , который хочу чтоб он сдох делаю так:
вот скажем поток который нам надо стопнуть , а затем заного запустить
Код

public class threadTest exteds Thread
{
    public void run()
    {
        int i =1;
        while(true)
        { 
             System.out.println(i);
              if(i>=500)
             {
                     i=1; 
              }
        }  
    }  
}

вот отсюдова:
Код

threadTest t = new threaTest();
t.setDaemon(true);
t.start();
t.stop//все пучком , останвливается...
// а вот как с самого начала опять запустить этот поток ?



Автор: SoulKeeper 25.4.2008, 16:14
Цитата(barin_Student @ 24.4.2008,  14:48)
Код

public void run(){
while(!quit){
   while((String s =r.readline())!=null)//  .. код чтения тут..., а если r.readline никогда не станет null , как мне остановить такой поток?
    {
     }
}
}


Добавлено @ 14:50
Код

если зависает где то на чтении - не поможет.. А вообще трассировку делали? где виснет то? 

по своему примеру , я могу еще добавить один класс , и указать где , и могу сказать почему виснет. Если надо , то могу запостить. 
Это паралельный вопрос , но основной , - это как мне остановить поток при такой ситуации?

Код

while((String s =r.readline())!=null && !quit)


Или цель стоит сделать максимально заумно?

Автор: Vurn 25.4.2008, 16:37
Кстати, никто не мешает, по идее, сделать проверку через .ready() на наличие доступных символов для чтения и, если символы есть - прочесть их в массив. Если ничего нет - отправить в сон не надолго.

Автор: barin_Student 26.4.2008, 08:26
Цитата(Vurn @ 25.4.2008,  19:37)
Кстати, никто не мешает, по идее, сделать проверку через .ready() на наличие доступных символов для чтения и, если символы есть - прочесть их в массив. Если ничего нет - отправить в сон не надолго.

Я так и сделал, сорри что не сказал.. Проверяю перед чтением на ready(), если нет то три раза жду и выхожу из цикла.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)