質問
次のような 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() メソッドに例外をスローする) を使用して、ブロッキング write() を停止したいと考えています。出来ますか?
編集[解決済み]:
唯一の方法は、出力ストリームを残酷に閉じ、書き込まれたビットの量を調べて、接続が送信中かどうかを確認することです。
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();
}
}
}
}
解決
一般に、I / Oのブロックでは、先に進む唯一の方法はリソースを閉じることです。@VolkerKが言うように、もう1つのアプローチは、ノンブロッキングI / Oを使用することですが、これはより困難です。
他のヒント
コードにThread.interrupt()
呼び出しを尊重させることができます。この呼び出しのjavadocを参照してください。
正確にはあなたが求めているものではありませんが、むしろ使用したいと思います java.nio そして
public abstract int select(long timeout) throws IOException
タイムアウトを検出するだけではありません。
これには割り込みを使用することをお勧めします。チェッカーはアップローダークラスで割り込みを呼び出す場合があります。
例 ジェネラコディセタグプレ
ドキュメントはこちら: http://docs.oracle.com/javase / tutorial / Essential / concurrency / interrupt.html