Java: бросить исключение в другой поток - PullRequest
3 голосов
/ 02 декабря 2011

У меня есть код Java, подобный этому:

private class Uploader implements Runnable
{
    // ...

public void start()
{
    t.start();
}

public void run()
{
        try {

        while(i=in.read())
        {
            output.write(i);    // THIS IS A BLOCKING CALL !!
        }

        } catch(ProtocolException e) { ... }
          catch(IOException e1) { ... }
}

private void restore()
{
        ...
}

private class Checker implements Runnable
{
            // ...

    @Override
    public void run()
    {
                // I WANT (IN A PARTICULAR MOMENT) TO THROW AN
                // EXCEPTION INTO THE Uploader RUN METHOD FROM HERE,
                // IS IT POSSIBLE? 
    }
}
}

Проблема в том, что у меня есть блокировка write () в методе Run (), поэтому я добавил новый поток, который проверяет, действительно лисоединение передает: если это не передача, я хочу остановить блокировку write () с помощью механизма исключений (выбрасывая исключение в метод run () другого потока из потока проверки).Возможно ли это?

РЕДАКТИРОВАТЬ [решено]:

Единственный способ - жестоко закрыть выходной поток и обработать количество записанных битов дляпроверьте, передает ли соединение:

private class Uploader implements Runnable
{
    private OutputStream output;

    private int readedBits;

    public void run()
    {
        try {

            while(i=in.read())
            {
                output.write(i);

                readedBits++;
            }

        } catch(IOException e1)
                {   
                    // ENTERS HERE IF RESTORE() IS CALLED
                }
    }

    private void restore()
    {
        try {
            output.close();
        } catch (IOException e) {}

        // Restore connection ....
    }

    private int getReadedBits()
    {   
        return this.readedBits;
    }

    private class Checker implements Runnable
    {
            // ...

        @Override
        public void run()
        {
            while(true)
            {
                try {
                    Thread.sleep(timeout);
                } catch (InterruptedException e1) {}

                if(lastReaded >= getReadedBits())
                    restore();
                else
                    lastReaded = getReadedBits();
            }
        }
    }
}

Ответы [ 4 ]

1 голос
/ 02 декабря 2011

Не совсем то, что вы просили, но я бы лучше использовал java.nio и
public abstract int select(long timeout) throws IOException
для обнаружения (не только) тайм-аутов.

1 голос
/ 02 декабря 2011

Вы можете сделать свой кодекс чести Thread.interrupt() Звоните.См. Javadoc этого вызова.

0 голосов
/ 02 декабря 2011

В общем случае с блокировкой ввода / вывода единственный способ двигаться дальше - закрывать ресурс. Как говорит @VolkerK, другой подход заключается в использовании неблокирующего ввода-вывода, что более сложно.

0 голосов
/ 02 декабря 2011

Я рекомендую использовать прерывания для этого. Средство проверки может вызывать прерывание для класса Uploader.

* 1003 Е.Г. *

private class Checker implements Runnable
{
        // ...
    Uploader uploader;
    public Checker(Uploader uploader) {
        this.uploader = uploader;
    }
    @Override
    public void run()
    {
            // CHECK
            if(failed) uploader.interrupt();
    }
}

Документация здесь: http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html

...