3

I have a java code like this:

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? 
    }
}
}

The problem is that i have a blocking write() in the Run() method, so I have added a new thread that checks whether or not the connection is transmitting: if it's not trasmitting I want to stop the blocking write() using the exception mechanism (throwing an exception to the other thread's run() method from the checker thread). Is it possible?

EDIT [SOLVED]:

The only way is to brutally close the output stream and to work on the amount of written bits to check whether the connection is transmitting:

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();
            }
        }
    }
}
Gino Cappelli
  • 55
  • 2
  • 7

4 Answers4

1

You can make your code honor Thread.interrupt() call. See javadoc of this call.

Victor Sorokin
  • 11,878
  • 2
  • 35
  • 51
  • Only a few, well-defined "blocking methods" are interruptible. If a thread is interrupted, a flag is set, but nothing else will happen until the thread reaches one of these well-defined interruption points. In my case, nothing happen! – Gino Cappelli Dec 02 '11 at 11:24
  • That's why I offered to make your code use method which pays attention to interruption. For example, blocking nio allows it. Other option would be do your work in small blocking chunks and after end of each chunk to check for interruption status of current thread explicitly. – Victor Sorokin Dec 02 '11 at 11:51
1

Not exactly what you've asked for but I'd rather use java.nio and
public abstract int select(long timeout) throws IOException
to (not only) detect timeouts.

VolkerK
  • 95,432
  • 20
  • 163
  • 226
0

I recommend using Interrupts for this. Checker may call interrupt on Uploader class.

E.g.

private class Checker implements Runnable
{
        // ...
    Uploader uploader;
    public Checker(Uploader uploader) {
        this.uploader = uploader;
    }
    @Override
    public void run()
    {
            // CHECK
            if(failed) uploader.interrupt();
    }
}

Documentation is here: http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html

forste
  • 1,103
  • 3
  • 14
  • 33
0

In general with blocking on I/O the only way to move on is to close the resource. As @VolkerK says, the other approach is to use non-blocking I/O, which is more difficult.

Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305