【问题标题】:Java: Throw an exception to another ThreadJava:向另一个线程抛出异常
【发布时间】:2012-01-11 09:54:28
【问题描述】:

我有一个这样的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();
            }
        }
    }
}

【问题讨论】:

    标签: java exception throws


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • Select 似乎不起作用:我的 write() 没有受支持的通道类型(例如 java.net.Socket)。
      【解决方案3】:

      我建议为此使用中断。 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

      【讨论】:

        【解决方案4】:

        您可以让您的代码兑现Thread.interrupt() 电话。请参阅此调用的 javadoc。

        【讨论】:

        • 只有少数定义明确的“阻塞方法”是可中断的。如果线程被中断,则设置一个标志,但在线程到达这些明确定义的中断点之一之前不会发生任何其他事情。就我而言,什么都没有发生!
        • 这就是为什么我提出让你的代码使用注意中断的方法。例如,阻止 nio 允许它。其他选择是在小的阻塞块中做你的工作,并在每个块结束后明确检查当前线程的中断状态。
        猜你喜欢
        • 2016-07-28
        • 2018-09-18
        • 2022-01-09
        • 2011-06-25
        • 2012-05-08
        • 2022-09-28
        • 1970-01-01
        • 2011-11-14
        • 2015-02-23
        相关资源
        最近更新 更多