Java:向另一个Thread抛出异常

时间:2011-12-02 10:47:52

标签: java exception throws

我有一个像这样的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? 
    }
}
}

问题是我在Run()方法中有一个阻塞的write(),所以我添加了一个 检查连接是否正在传输的新线程:如果它没有传输我想要使用异常机制停止阻塞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 个答案:

答案 0 :(得分:1)

您可以使代码荣誉Thread.interrupt()来电。请参阅此调用的javadoc。

答案 1 :(得分:1)

不完全是你所要求的,但我宁愿使用java.nio
public abstract int select(long timeout) throws IOException
(不仅)检测超时。

答案 2 :(得分:0)

我建议使用Interrupts。 Checker可能会在Uploader类上调用中断。

E.g。

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

答案 3 :(得分:0)

通常,在I / O上阻塞是继续前进的唯一方法是关闭资源。正如@VolkerK所说,另一种方法是使用非阻塞I / O,这更难。