How do I write native code which responds to `Thread.interrupt()`? - java

In Java, all the standard blocking methods can be interrupted by calling Thread.interrupt(), but what if we have Java bindings wrapping a native library which does its own I/O? How then should the native code hook into the Thread and respond to calls to Thread.interrupt()?

Example code
For a full writeup, including runnable sample code, see https://github.com/NWilson/javaInterruptHook.
How does Thread.interrupt() work?
In Sun's JRE (and OpenJDK), interrupt() is able to wake up a few low-level operations itself, such as waiting on a monitor (Object.wait()), and provides an internal hook for higher-level code to be notified of the interruption. This is provided through JavaLangAccess.blockedOn(), which can actually be called directly by your code through sun.misc.SharedSecrets, if you're willing to use Sun-specific implementation details.
As far as I can tell, there's only one public, documented way to register for that notification, which is using java.nio.channels.spi.AbstractSelector. This is a partial implementation of Selector which does the dirty work for you of hooking up the JavaLangAccess.blockedOn() notification to the selector's wakeup() method.
How to implement this all
Implement AbstractSelector to make your own selector; most of the methods are not relevant so just ignore them and put in stubs to shut up the compiler. When you are about to enter your JNI blocking method, call the AbstractSelector begin() method, then call end() when the JNI call has returned.
The selector should cancel the JNI method in its implementation of wakeup().
Rough code
(For a full running example see the github repo linked at the top.)
class NativeTask {
public NativeTask() {}
public void doTask()
throws InterruptedException {
NativeTaskSelector selector = new NativeTaskSelector(this);
try {
selector.registerStart();
doTask0(); // native method
if (Thread.interrupted())
throw new InterruptedException();
} finally {
selector.registerEnd();
try { selector.close(); } catch (IOException impossible) {}
}
}
/* The long-running native operation. */
native private void doTask0();
public void wakeupTask() { wakeupTask0(); }
/* A way to cause the native operation to wake up. */
native private void wakeupTask0();
}
class NativeTaskSelector extends AbstractSelector {
protected NativeTaskSelector(NativeTask task_) {
super(null);
task = task_;
}
public void registerStart() { begin(); }
public void registerEnd() { end(); }
final private NativeTask task;
#Override
public Selector wakeup() {
task.wakeupTask();
return this;
}
#Override
protected void implCloseSelector() throws IOException {
}
#Override
protected SelectionKey register(AbstractSelectableChannel arg0, int arg1,
Object arg2) {
throw new UnsupportedOperationException();
}
#Override
public Set<SelectionKey> keys() {
throw new UnsupportedOperationException();
}
#Override
public int select() throws IOException {
throw new UnsupportedOperationException();
}
#Override
public int select(long arg0) throws IOException {
throw new UnsupportedOperationException();
}
#Override
public int selectNow() throws IOException {
throw new UnsupportedOperationException();
}
#Override
public Set<SelectionKey> selectedKeys() {
throw new UnsupportedOperationException();
}
}

Related

Check if another Thread is interrupted, without polling

I'd like to check to see if a Thread is Interrupted, from some other Thread, without polling this to check - i.e. some kind of monitor.
Specifically, what I am trying to do is force-kill (Stop) a Thread when it is Interrupted. I will include a code example below of a trivial example of what I have done so far - it works, but polling to check if the Thread is interrupted is sub-optimal and I would like to avoid this.
public class ThreadTest
{
public static void main(final String[] args) throws InterruptedException
{
final Thread outerThread = new Thread()
{
#Override
public void run()
{
// Need to externally monitor the thread to detect and process interrupts (for cancellation)
final Thread thread = Thread.currentThread();
new Thread()
{
#Override
public void run()
{
while (true)
{
try
{
Thread.sleep(500);
}
catch (final InterruptedException e)
{}
if (thread.isInterrupted())
{
// Then kill it
thread.stop();
return;
}
}
}
}.start();
uninterruptibleForever();
}
};
outerThread.start();
// Ensure the thread has time to start up
Thread.sleep(500);
outerThread.interrupt();
// The thread should terminate at this point and not continue.
}
/** Some arbitrary task that runs forever and ignores interrupts */
public static void uninterruptibleForever()
{
while (true)
{
System.out.println(MessageFormat.format("I''m still running at {0}", new Date().toLocaleString()));
}
}
}
I can't recommend strongly enough that you don't use Thread#stop().
It should never have existed, was deprecated very quickly and frankly should have been removed about 20 years ago.
You have no idea what the thread is doing when you stop it and it is very easy to corrupt shared objects and leave external resources (e.g. files) in an invalid state.
Suppose the thread is in the middle of resizing a shared ArrayList<> there's risk the object will be corrupted and your whole program fails intermittently in ways you cannot fix.
Do not use Thread#stop() it is broken and cannot be fixed.
It's a terrible feature of Java that it leads people into invalid techniques regarding threads.
Caveat over - how about just overriding interrupt() in a sub-class?
public void interrupt(){
this.stop();
}
You've decided to sub-class Thread (rather than Runnable) so this will "work". "work" in the sense of what you're doing. Not actually work or anything.
The only valid way to solve this is have the thread you want to terminate co-operate by responding to interrupt() as an instruction to come to a suitable point and then terminate cleanly.
Or you can create another flag indicating the thread should end.
I don't know why you need to monitor the thread externally. But here is a small sample how you could do it if you really need it:
import java.util.LinkedList;
import java.util.List;
public abstract class MonitoredCallable implements Runnable {
private final List<InterruptedHandler> interruptedHandlers = new LinkedList<>();
protected abstract void runInternal() throws Exception;
#Override
public final void run() {
try {
runInternal();
} catch(Exception ex) {
}
for (InterruptedHandler interruptedHandler : interruptedHandlers) {
interruptedHandler.threadInterrupted(this);
}
}
public void addInterruptedHandler(InterruptedHandler interruptedHandler) {
this.interruptedHandlers.add(interruptedHandler);
}
public static interface InterruptedHandler {
void threadInterrupted(Thread t);
}
}
Now just use it like this:
MonitoredThread mt = new MonitoredThread() {
#Override
protected void runInternal() throws Exception {
//dosomething
}
};
mt.addInterruptedHandler(t->t.stop());

Detecting write to standard error stream

Is there no way (regardless of how "hacky" it is) to detect when Java's System.err has been written to in order to be able to execute logic if and when this happens? — I'm currently working with a custom subclass of Thread (let's call it SwallowingThread) which swallows a number of exceptions in its implementation of Thread.run() in a manner similar to the following code:
public final class SwallowingThread extends Thread {
...
#Override
public void run() {
ServerSocket socket = new ServerSocket(80, 100);
try {
Socket connected = socket.accept();
// Do stuff with socket here
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
In my code, however, I want to be able to handle cases of UnknownHostException and IOException which occur while using an instance of SwallowingThread; Is there no way to detect that this catching and printing to standard error after it has occured? — I had originally tried writing a UncaughtExceptionHandler to do this only to find out that it isn't catching the exceptions because they were swallowed rather than simply being e.g. wrapped in a RuntimeException and thrown onward.
Of course, a "better" way of solving this problem is to re-write the logic for the class, but is there no quick-and-dirty way of solving this issue without having to touch SwallowingThread?
You can implement your own class (I call it DelegatingErrorPrintStream) derived from PrintStream which notifies you if there's new output, and then delegates to System.err
And now you can set YOUR DelegatingErrorPrintStream as output stream for System.err using
System.setErr(err);
Full example including usage:
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
public class ErrorNotifierExample {
private static final class ErrorDelegatingPrintStream extends PrintStream {
public ErrorDelegatingPrintStream(PrintStream defaultErr)
throws FileNotFoundException, UnsupportedEncodingException {
super(defaultErr);
}
#Override
public void print(boolean b) {
super.print(b);
notifyListener(b);
}
#Override
public void print(char c) {
super.print(c);
notifyListener(c);
}
#Override
public void print(int i) {
super.print(i);
notifyListener(i);
}
#Override
public void print(long l) {
super.print(l);
notifyListener(l);
}
#Override
public void print(float f) {
super.print(f);
notifyListener(f);
}
#Override
public void print(double d) {
super.print(d);
notifyListener(d);
}
#Override
public void print(char[] s) {
super.print(s);
notifyListener(s);
}
#Override
public void print(String s) {
super.print(s);
notifyListener(s);
}
#Override
public void print(Object obj) {
super.print(obj);
notifyListener(obj);
}
#Override
public PrintStream append(CharSequence csq, int start, int end) {
notifyListener(csq); // TODO will need some special handling
return super.append(csq, start, end);
}
private void notifyListener(Object string) {
// TODO implement your handling here. System.out printing is just an
// example.
System.out.println(String.valueOf(string));
}
}
public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {
ErrorDelegatingPrintStream errReplacement = new ErrorDelegatingPrintStream(System.err);
System.setErr(errReplacement);
System.err.println("TEST01");
throw new RuntimeException("just a test output for ERROR handling");
}
}
As several persons already suggested, you may go with a custom PrintStream.
It will replace the standard error stream but also encapsulate it and call it when needed.
Since the exceptions and stack traces are what you are interested in, overriding print(String) should be enough (println(String) already calls this method + newLine()).
The stream could look like that :
import java.io.PrintStream;
public class CustomPrintStream extends PrintStream {
public CustomPrintStream(final PrintStream out) {
super(out);
}
#Override
public void print(final String s) {
super.print(s);
// some String is written to the error stream, Do something !
}
}
You would use it that way, at the beginning of your application, just call
System.setErr(new CustomPrintStream(System.err));

java thread wait and auto wake up

I have an web application which accept some data from user to create a task, then the task should be executed.
Since the execution of the Task is to download something from the internet which will cost some time, so I tried to create a new Thread to do the job.
This is my idea:
create a LoaderThread used to download data. And the LoaderThread hold a field of ArrayList used for put the Task.
A Servlet to handle the request and response.
When the Servlet startup, start the LoaderThread
During the servlet run, add task to the LoaderThread.
This is the code(some of them is omitted):
public class RwdServlet extends HttpServlet {
private StaticMapLoader loader;
#Override
public void init() throws ServletException {
super.init();
loader = new StaticMapLoader();
loader.startRunning();
}
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Task t=createTask(req);
loader.addTask(t);
}
#Override
public void destroy() {
loader.stopRunning();
}
}
public class StaticMapLoader extends Thread {
private List<Task> tasks = new ArrayList<Task>();
private boolean running = false;
#Override
public void run() {
while (running) {
if (tasks.size() > 0) {
Task t = tasks.get(0);
log.info(t);
if (t != null && t.status == Status.waiting) {
tasks.remove(0);
t.status = Status.running;
downLoad(t);
}
}
}
}
private void downLoad(Task t) {
//download file
}
public void addTask(Task t) {
tasks.add(t);
}
public void startRunning() {
running = true;
this.start();
}
public void stopRunning() {
running = false;
this.interrupt();
}
}
The above code worked, but I found that even the tasks were empty and there are no new task added, the loop will keep running.
So I though if I can make the LoaderThread suspend when there are no tasks, and notify it when new task come out.
So I tried this:
#Override
public void run() {
while (running) {
if (tasks.size() > 0) {
Task t = tasks.get(0);
log.info(t);
if (t != null && t.status == Status.waiting) {
tasks.remove(0);
t.status = Status.running;
downLoad(t);
}
} else {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
I tried to call the wait() if the tasks is empty.
But I do not know how to wake up it?
Also, is there anything I should know to improve the application?
BWT, is it possible that more than one LoaderThread instance will be created? If so , how to avoid it?
It seems that I can use other implementation, but I wonder if my case is refactor-able?
Since I want to learn some thing I have missed. :) Thanks.
Your requirements are the standard usage of ExecutorService, so I would recommend you to use ExecutorService and not reinvent the wheel.
Base on code you provided, your servlet should look like this:
public class RwdServlet extends HttpServlet {
private ExecutorService loader;
#Override
public void init() throws ServletException {
super.init();
loader = Executors.newCachedThreadPool();//or use some other executor, google about difference between them
}
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Task t=createTask(req); //assume that task implements Runnable or Callable
loader.submit(t); // submit a task to executor after this line your task will start execution in another thread
}
#Override
public void destroy() {
loader.shutdown();//this will destroy executor service but before that it will wait until all already submitted tasks will be executed
}
}
See link with example
Your use case calls for an ExecutorService and you have started reimplementing it from scratch. Better stop now and use the finished, bug-free, flexible, and powerful product from the standard library.

GWT. Throw exception inside onFailure()

It is possible to throw exception inside onFailure() method of GWT's RPC call? Because this method will be called later, after server response, I apologize that here may happen something bad..
For example:
public void method() {
try {
rpc.invoke(new AsyncCallback<Void>() {
#Override
public void onSuccess(Void arg0) {}
#Override
public void onFailure(Throwable arg0) {
throw new RuntimeException("Error message"); //HERE
}
});
}
catch (Exception e) {
Window.alert(e.getMessage()); // AND CATCH ABOVE EXCEPTION HERE
}
}
I usually use the following approach on my GWT projects:
1) Create an MyExceptionsHandler:
#Singleton
public class MyExceptionsHandler implements
GWT.UncaughtExceptionHandler,
RpcFailureEvent.Handler, // create corresponding GwtEvent-s
AnyOtherErrorEvent.Handler {
public MyExceptionsHandler(EventBus evenBus) {
eventBus.addHandler(RpcFailureEvent.TYPE, this);
eventBus.addHandler(AnyOtherErrorEvent.TYPE, this);
}
// implement corresponding methods for interfaces
}
2) On entry point:
GWT.setUnchaughtExceptionHandler(myExceptionHandler);
3) In any other place you have an error, which you don't know how to handle:
rpc.invoke(new AsyncCallback<Void>() {
#Override
public void onSuccess(Void arg0) {}
#Override
public void onFailure(Throwable arg0) {
eventBus.fireEvent(new RpcFailureEvent(<any context info you think helpful>));
}
});
Yes, it's possible.
#Override
public void onFailure(Throwable arg0) {
throw new RuntimeException(arg0);
}
This code is absolutely valid. But to what purpose are you creating and throwing a new instance of RuntimeException?
At that if you write
new RuntimeException("Error message")
you lose all information about occurred exception.
And don't forget that in GWT all calls from client to a remote service are handled asynchronously. And the onFailure() callback method are called immediatly when an asynchronous call fails to complete normally.
No, you can't. Well, you can throw the exception, but it won't be handled by the catch block you defined, since the AsyncCallback is an anonymous class that does not run in the same scope and is not called at the same time as your catch block.
You can however try to use GWT.setUncaughtExceptionHandler(), see the details at http://google-web-toolkit.googlecode.com/svn/javadoc/latest/com/google/gwt/core/client/GWT.html.

BlackBerry class equivalent to AsyncTask?

My requirement is to have a thread that maintains a socket connection between a BlackBerry device and a server and exchanges commands, similar to request and response.
My problem is that I need to have this thread running in the background all the time and keep the UI available to the user. So, when there is a command from the server, this thread parses it and updates the UI and also if there's an action from the BlackBerry user, it sends it to the server and the server in turn handles it.
I developed the same application in Android using AsyncTask and it's working well. But in BlackBerry, as there's no such class, I used the invokeLater() option. The communication works fine between the server and the BB device, but the UI is frozen on the BlackBerry.
Anyone have any idea how to get this right?
Vishal is on the right track, but a little more is needed to match Android's AsyncTask. Since enums and generics aren't available with Java 1.3 on BlackBerry, you can't match the Android API perfectly.
But, you could do something like this (not tested ... this is just a starting point for you):
import net.rim.device.api.ui.UiApplication;
public abstract class AsyncTask {
public static final int FINISHED = 0;
public static final int PENDING = 1;
public static final int RUNNING = 2;
private int _status = PENDING;
private boolean _cancelled = false;
private Thread _worker;
/** subclasses MUST implement this method */
public abstract Object doInBackground(Object[] params);
protected void onPreExecute() {
// default implementation does nothing
}
protected void onPostExecute(Object result) {
// default implementation does nothing
}
protected void onProgressUpdate(Object[] values) {
// default implementation does nothing
}
protected void onCancelled() {
// default implementation does nothing
}
protected void onCancelled(Object result) {
onCancelled();
}
public final int getStatus() {
return _status;
}
public final boolean isCancelled() {
return _cancelled;
}
public final boolean cancel(boolean mayInterruptIfRunning) {
if (_status == FINISHED || _cancelled) {
return false;
} else {
_cancelled = true;
if (mayInterruptIfRunning && _status == RUNNING) {
// NOTE: calling Thread.interrupt() usually doesn't work
// well, unless you don't care what state the background
// processing is left in. I'm not 100% sure that this is how
// Android's AsyncTask implements cancel(true), but I
// normally just cancel background tasks by letting the
// doInBackground() method check isCancelled() at multiple
// points in its processing.
_worker.interrupt();
}
return true;
}
}
protected final void publishProgress(final Object[] values) {
// call back onProgressUpdate on the UI thread
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
onProgressUpdate(values);
}
});
}
private void completeTask(final Object result) {
// transmit the result back to the UI thread
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
if (isCancelled()) {
onCancelled(result);
} else {
onPostExecute(result);
}
// TODO: not sure if status should be FINISHED before or after onPostExecute()
_status = FINISHED;
}
});
}
public AsyncTask execute(final Object[] params) throws IllegalStateException {
if (getStatus() != PENDING) {
throw new IllegalStateException("An AsyncTask can only be executed once!");
} else {
try {
onPreExecute();
_worker = new Thread(new Runnable() {
public void run() {
try {
// run background work on this worker thread
final Object result = doInBackground(params);
completeTask(result);
} catch (Exception e) {
// I believe if Thread.interrupt() is called, we'll arrive here
completeTask(null);
}
}
});
_status = RUNNING;
_worker.start();
} catch (Exception e) {
// TODO: handle this exception
}
}
return this;
}
}
Also, it's important to keep in mind the Threading Rules for Android's AsyncTask, which apply to the above implementation, too:
Threading rules
There are a few threading rules that must be followed
for this class to work properly:
The AsyncTask class must be loaded on the UI thread. This is done
automatically as of JELLY_BEAN.
The task instance must be created on
the UI thread.
execute(Params...) must be invoked on the UI thread.
Do not call onPreExecute(), onPostExecute(Result),
doInBackground(Params...), onProgressUpdate(Progress...) manually.
The task can be executed only once (an exception will be thrown if a
second execution is attempted.)
You can create a Class that extends my implementation of class AsyncTask. Good Luck :)
Here the methods onPreExecute, onPostExecute are executed on UI thread and doInBackground is called on worker thread. Since onPreExecute, onPostExecute are abstract you can override them and provide your implementation like showing and dismissing progress dialog.
The sequence in which methods get's executed is
1) onPreExecute
2) doInBackground
3) onPostExecute
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.Dialog;
public abstract class AsyncTask {
Runnable runnable;
Thread threadToRun;
public abstract void onPreExecute();
public abstract void onPostExecute();
public abstract void doInBackground();
public void execute() {
try {
runnable = new Runnable() {
public void run() {
// TODO Auto-generated method stub
UiApplication.getUiApplication().invokeLater(
new Runnable() {
public void run() {
// TODO Auto-generated method stub
onPreExecute();
}
});
doInBackground();
UiApplication.getUiApplication().invokeLater(
new Runnable() {
public void run() {
// TODO Auto-generated method stub
onPostExecute();
}
});
}
};
threadToRun = new Thread(runnable);
threadToRun.start();
} catch (Exception e) {
// TODO: handle exception
Dialog.alert("Async Error Occured. " + e.toString());
}
}
}

Categories

Resources