Как убить поток, который ожидает блокировки функции в Java? - PullRequest
9 голосов
/ 06 августа 2010

У меня есть тема:

Thread t = new Thread(){
    public void run(){
        ServerSocketConnection scn = (ServerSocketConnection)
                Connector.open("socket://:1234");
        // Wait for a connection.
        SocketConnection sc = (SocketConnection) scn.acceptAndOpen();
       //do other operation
    }
};
t.start();

Допустим, ни один клиент не подключается к Серверу, поэтому этот поток будет заблокирован. Теперь я хочу уничтожить вышеупомянутый поток t? Как я могу убить его?

Ответы [ 7 ]

8 голосов
/ 06 августа 2010

Thread.interrupt() будет не прерывать поток, заблокированный в сокете.Вы можете попытаться вызвать Thread.stop() или Thread.destroy(), но эти методы устарели (редактировать: фактически, отсутствует в J2ME) и в некоторых случаях не работают, по причинам, которые вы можете прочитать о здесь .Как упоминается в этой статье, лучшее решение в вашем случае - закрыть сокет, на котором вы блокируете:

В некоторых случаях вы можете использовать специфические для приложения приемы.Например, если поток ожидает известного сокета, вы можете закрыть сокет, чтобы поток немедленно вернулся.К сожалению, на самом деле нет какой-либо техники, которая работает в целом.Следует отметить, что во всех ситуациях, когда ожидающий поток не отвечает на Thread.interrupt, он также не будет отвечать на Thread.stop.К таким случаям относятся преднамеренные атаки типа «отказ в обслуживании» и операции ввода-вывода, для которых thread.stop и thread.interrupt не работают должным образом.

0 голосов
/ 23 ноября 2012

Я только что зашел на эту страницу в поисках того же ответа. Я нашел способ закрыть Темы, и вот что я делаю, чтобы завершить работу сервера:

private Thread serverThread;

public void setUp(){
    //Run the server
    serverThread = new Thread() {
        public void run() {
            try {
                new Server(); //it calls acceptAndOpen() here
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    };
    serverThread.start();
}

public void tearDown() {
    serverThread = null;
    System.gc();
}

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

Обратите внимание: Это далеко не идеально, мы никогда не должны зависеть от gc, чтобы выполнять свою работу, но, похоже, работает каждый раз, когда я пробовал это

0 голосов
/ 06 августа 2010

Я думаю, вам просто нужно закрыть соединение - просто сделайте scn полем потока и реализуйте:

public void stop() {
  scn.close();
}

и код вашего основного метода для корректного выхода на IOException илидругое указание, что вы сделали (как вы, вероятно, уже сделали).

0 голосов
/ 06 августа 2010

В вашем основном потоке (когда вы хотите прервать поток принятия) вызовите scn.close(). acceptAndOpen должен затем выбросить IOException, который вы можете перехватить, а затем грациозно завершить принятие-поток.

ServerSocketConnection scn =
    (ServerSocketConnection) Connector.open("socket://:1234");

Thread t = new Thread(){
    public void run(){
        // Wait for a connection.
        try {
            SocketConnection sc = (SocketConnection) scn.acceptAndOpen();
            //do other operation
        } catch (IOException e) {
            // Log the exception
        }
    }
};

t.start();

// ...

// Somewhere else...
// Cancel the acceptAndOpen.
scn.close();

Хорошей идеей было бы ввести механизм синхронизации , чтобы вы не закрывали сокет сразу после того, как acceptAndOpen прошел.

0 голосов
/ 06 августа 2010

Сделать основной поток РЕЗЬБА МОНИТОРА (откуда вы создали эту новую тему) join () для этой темы.Если по истечении заданного времени ожидания этот поток не «присоединяется», вы можете игнорировать (обнулять) этот поток.Это даст вам дополнительную функциональность, добавив тайм-аут для блокировки потока.

0 голосов
/ 06 августа 2010

Вызов Thread.interrupt () . Операции блокировки обычно выдают InterruptedException , если Thread , в котором они выполняются, прерывается.

0 голосов
/ 06 августа 2010

Вы можете позвонить thread.interrupt().Это добавит InterruptedException в вашу ветку

...