3

我有一个这样的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(),所以我添加了一个新线程来检查连接是否正在传输:如果它没有传输,我想使用异常机制(从检查器线程向另一个线程的 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

4 回答 4

1

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

于 2011-12-02T10:50:58.097 回答
1

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

于 2011-12-02T11:04:14.603 回答
0

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

例如

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

于 2011-12-02T10:58:59.477 回答
0

一般来说,阻塞 I/O 的唯一方法是关闭资源。正如@VolkerK 所说,另一种方法是使用非阻塞 I/O,这更加困难。

于 2011-12-02T11:38:48.897 回答