0

i have two java classes running on different threads. one class makes a connection to the internet while the other class monitors the connection status. i want to throw an IOException incase the class making a connection delays while reading server response, at the sametime i dont want to throw an exception if there is some response being read from the Server.

i came up with this code.

my problem is i want to throw an IOException in class NetworkMonitor which will be caught by NetworkConnector class which is the main class. however the compiler complains of uncaught exception.

  public class NetworkConnector{
  //method that connects to the server to send or read data.
  public String sendData(String url ,String data){
     try{

        //start the monitor before we read the serverResponse
        new NetworkMonitor().startMonitor();

        int read ;
        while ((read = inputStream.read()) != -1) {
           //read data.
           sb.append((char) read);

           //monitor if we are reading from Server if not reading count 10 to 0 and throw IoException. 
           new NetworkMonitor().resetCounter();
        }

     } catch(IOException ex){
        //all IOException should be caught here.
     }

  }

}

//class that monitors if there a network activity occuring.

  public class NetworkMonitor implements Runnable {

  private final int WAITTIME =10;
  private int counter = WAITTIME;


  public void run(){
     try{

        while(counter > 0){
           //waiting here
           counter--; //decrement counter. 
           Thread.sleep(1000);     
        }

        //when counter is at zero throw iOexception 
        throw new IOException("Failed to get server Response");

     } catch(InterruptedException e){
        System.out.println(e.getMessage());
     } catch(IOException e){
        //i want to throw the IOEception here since the exception should 
        //be caught by the networkConnector class not the monitor class but the compiler complains.
        // unreported exception java.io.IOException; must be caught or declared to be thrown
        throw new IOException(e.getMessage());

        //throwing another exception type is okay ===>why cant we throw the same type of exception we caught.
         throw new IllegalArgumentException(e.getMessage()); 
     }


  }

  //reset the counter if called.
  public void resetCounter(){
     counter = WAITTIME;
  }

  public void startMonitor(){
     Thread t = new Thread(this);
     t.start();
  }

}

4

4 回答 4

2

你有一个更基本的问题

  • 一个线程中抛出的异常需要传递给另一个线程。您可以使用 ExecutorService 和 Future 来执行此操作。
  • 要实现您的超时,您可以使用 ScheduledExecutorService。这将允许您安排延迟和可取消的任务。
  • 一个线程中抛出的异常不会解除阻塞读取。您需要关闭连接以解除阻塞,这将导致 IOException。
  • 一旦你有了这些,你就可以使用 Callable 而不是 Runnable 来抛出一个检查异常。

而不是睡1秒钟,10次。你可以只睡10秒钟。

于 2012-12-11T09:28:07.777 回答
0

基本设计有缺陷。异常不会自动跨线程边界传播。

您可能应该考虑使用非阻塞 I/O 来做您想做的事情。

于 2012-12-11T09:25:13.517 回答
0

我想,您正试图在两个线程之间实现某种通信。例外并不是那么优雅的解决方案。我建议更改您的代码以适应与volatileand blocking queuesorexecutor service等​​更好的通信future方式。实现此目的的一种方法如下:

LinkedBlockingQueue在主类中创建一个,从那里分叉这两个线程:

LinkedBlockingQueue<Integer> blockingQueue = new LinkedBlockingQueue<Integer>(
        1);

将此队列传递给两个线程。volatile在您的网络监视器类中创建一个成员:

volatile boolean isAllowed = true;

将您的 while 条件更改NetworkConnector

while ((read = inputStream.read()) != -1 && networkMonitor.isAllowed()) { 

在您的NetworkMonitor's run方法中,更改 while 条件:

while(isAllowed) {
Integer i = blockingQueue.poll(10, TimeUnit.SECONDS);
if(i==null) 
  isAllowed = false;
}

NetworkConnector's while loop在里面append加上这个:

blockingQueue.add(1);

本质上,我们将一个整数添加到队列中;一旦监视器线程得到一个非空整数,它最多等待 10 秒。连接器线程有 10 秒的时间将整数放入队列,如果没有,它的 while 循环会中断。一旦脱离循环,做任何你需要做的事情。

没有运行这个,这只是一个基于初步想法的例子。希望这可以帮助。

于 2012-12-12T10:30:08.847 回答
-1

run()是从Runnable. 在可运行接口中,没有受检异常定义,因此您无法从那里抛出受检异常。但是你可以用 throwRuntimeException来代替。

于 2012-12-11T09:29:14.753 回答