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() があることです。そのため、接続が送信されているかどうかをチェックする新しいスレッドを追加しました。送信していない場合は、ブロックしている 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

あなたが求めたものとは正確には異なりますが、私はむしろjava.nioを使用し て、(だけでなく) タイムアウトを検出したいと考えています。
public abstract int select(long timeout) throws IOException

于 2011-12-02T11:04:14.603 に答える
1

コードを尊重してThread.interrupt()電話をかけることができます。この呼び出しの javadoc を参照してください。

于 2011-12-02T10:50:58.097 に答える
0

一般に、I/O をブロックする場合、先に進む唯一の方法はリソースを閉じることです。@VolkerK が言うように、もう 1 つのアプローチはノンブロッキング I/O を使用することですが、これはより困難です。

于 2011-12-02T11:38:48.897 に答える
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 に答える