We are working on a project to handle virtual machine managers from a Java application.
At the moment, we faced a problem where some instructions must be considered as a task because they require more time. Theses taks can also end with errors or be a success, and we can't know the result from the application unless we request the state of the task to the VM hypervisor.
To have a smooth application we wanted to have a CommandManager to handle the differents request to theses hypervisors in separated threads. The problem is that these Command might return specific errors such as that we used to catch in the view to display revelant information to the user but when we implement Runnableon our Commands interface, we can't throw any exception out of that thread back to reach the view.
What could I do to keep notifying the user of the errors that happened and their nature?
Sorry for my english!
Lets see the code below for a brief example :
First the Command
class ChangeMemorySize extends Command {
private String name;
private int memorySizeMb;
public ChangeMemorySize(Hypervisor hypervisor, String server,
String name, int memory) {
super(hypervisor, server);
this.name = name;
this.memorySizeMb = memory;
}
protected void execute() throws ConnectionException,OperationException{
//Some code here
}
public void run() //CANT THROW ANYTHING HERE :throws VmConfigFault,
try{
execute();
}catch{Exception e){
// I have to catch it all here!
}
This isn't real code this is just an example. This command would then be passed to a manager who would run it in another thread. But I loose all the specifics exception that I used to notify the user of what really happened in there!
Use an ExecutorService and do one of two things.
First you can store all results in a Future and when you want to know if an Exception occurs just invoke Future.get() and handle any exception.
Second you can create the ExecutorService with a ThreadFactory in which you set it a knew UncaughtExceptionHandler like
final UncaughtExceptionHandler handler = new UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
// notify error
}
});
Executor executor = Executors.newFixedThreadPool(1, new ThreadFactory() {
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
thread.setUncaughtExceptionHandler(handler);
return thread;
}
});
While I agree with #John Vint that ExecutorService with an UncaughtExceptionHandler is a good approach, if for some reason you really want to stick with Runnables, I'd suggest that your base class, Command, have some fields/getters for status and Exception. e.g.
Enum Status {FAILED, CANCELLED, SUCCESS};
// protected so subclasses can set them
protected Status status;
protected Exception exception; // null means none
public Status getStatus();
public Exception getException();
You might even want to add a result field to really mimic a Callable.
For simplicity, then add a method that subclasses can call in the catch clause
protected void s***Happenned(Exception e) {
this.exception = e;
status = FAILED;
// any standard cleanup can go here too...
}
Related
I've a method who return a result (return an integer), my method is executed in a Thread for load 40 000 objects, i return an integer who count the number objects loaded. My question is, How return the int with the Thread ? Actually, the result is returned directly and is equal to 0.
public int ajouter(params) throws DaoException, ConnectException {
final ProgressDialog dialog = ProgressDialog.show(mActivity, "Title",
"Message", true);
final Handler handler = new Handler() {
public void handleMessage(Message msg) {
dialog.dismiss();
}
};
Thread t = new Thread() {
public void run() {
try {
Str_Requete = "SELECT * FROM Mytable";
ResultSet result = ExecuteQuery(Str_Base, Str_Requete);
Index = addObjects(result);
handler.sendEmptyMessage(0);
} catch (SQLException e) {
e.printStackTrace();
}
}
};
t.start();
return Index;
}
When i call my method in my mainActivity :
int test = myObjs.ajouter(params);
test is equal to 0, the value is returned directly...
My constraint is didnt use AsyncTask.
The whole point of using a Thread is not to block the calling code while performing the task of the thread. Thread.start() returns immediately, but in the meantime a new thread is started in parallel to the current thread which will execute the code in the run() method.
So by definition there is no such thing as returning a value from a thread execution. You have to somehow send a signal back from the thread that performed the task to the thread in which you need the result. There are many ways of doing this, there's the standard Java wait/notify methods, there is the Java concurrency library etc.
Since this is Android, and I assume your calling code is running on the main thread, it's probably wise to use the functionality of Handler. And in fact, you are already doing that - you have a Handler that closes the dialog when the thread is done with its work - but for some reason you seem to expect the result of that work to be ready before it has even started. It would be reasonable to extend your existing Handler with some code that does something with the calculated value and remove the code that returns the value of a variable before or at the same time as it's being calculated by another thread.
I also strongly encourage you to study some concurrency tutorial such as Oracle's concurrency lesson or Android Thread guidelines to really understand what's going on in the background. Writing concurrent code without mastering the concepts is bound to fail sooner or later, because it's in the nature of concurrency that multiple things are happening at the same time, will finish in random order etc. It may not fail often, but you will go crazy wondering why something that works 90% of the time suddenly fails. That's why topics such as atomicity, thread synchronization etc are critical to comprehend.
Edit: Simple Android example of starting a worker thread, performing some work, posting back event to main thread.
public class MyActivity extends Activity {
private Handler mHandler = new Handler();
...
private void doSomeWorkInBackground() {
new Thread() {
public void run() {
// do slow work, this may be blocking
mHandler.post(new Runnable() {
public void run() {
// this code will run on main thread,
// updating your UI or whatever you need.
// Hence, code here must NOT be blocking.
}
});
}
}.start();
// This code will be executed immediately on the main thread, and main thread will not be blocked
}
You could in this example also use Activity.runOnUiThread(Runnable).
Please consider however that AsyncTask basically wraps this kind of functionality in a very convenient way, so if it suits your purposes you should consider using AsyncTask.
If you dont want to use AsyncTask or ForkJoin, then you could implement an Interface e.g. callback in your main class.
In your Example you dont wait until the Thread is done... thread.join
One Solution:
Your Thread is a extra class with an constructor to hold the reference to the calling class.
public Interface callback
{
public int done();
}
public class main implements callback
{
...
CustomThread t = new CustomThread(this)
...
}
public class CustomThread extends Thread
{
private Callback cb;
public CustomThread(Callback cb)
{
this.cb=cb;
}
.
.
.
//when done
cb.done(int)
}
I have a java application which has to be run as a Linux process. It connects to a remote system via socket connection. I have two threads which run through whole life cycle of the program. This is the brief version of my application entry point:
public class SMPTerminal {
private static java.util.concurrent.ExcecutorService executor;
public static void main(String[] args) {
executor = Executors.newFixedThreadPool(2);
Runtime.getRuntime().addShutdownHook(new Thread(new ShutdownHook()));
run(new SMPConsumer());
run(new SMPMaintainer());
}
public static void run(Service callableService) {
try {
Future<Callable> future = executor.submit(callableService);
run(future.get().restart());
} catch (InterruptedException | ExcecutionException e) {
// Program will shutdown
}
}
}
This is Service interface:
public interface Service() {
public Service restart();
}
And this is one implementation of Service interface:
public class SMPConsumer implements Callable<Service>, Service {
#Override
public Service call() throws Exception {
// ...
try {
while(true) {
// Perform the service
}
} catch (InterruptedException | IOException e) {
// ...
}
return this; // Returns this instance to run again
}
public Service restart() {
// Perform the initialization
return this;
}
}
I reached this structure after I have headaches when a temporary IO failure or other problems were causing my application shutdown. Now If my program encounters a problem it doesn't shutdown completely, but just initializes itself from scratch and continues. But I think this is somewhat weired and I am violating OOP design rules. My questions
Is this kind of handling failures correct or efficient?
what problems do I may encounter in future?
Do I have to study about any special design pattern for my problem?
You might not have noticed, but your run method waits for the callableService to finish execution before it returns. So you are not able to start two services concurrently. This is because Future.get() waits until the task computation completes.
public static void run(Service callableService) {
try {
Future<Callable> future = executor.submit(callableService);
run(future.get().restart()); // <=== will block until task completes!
} catch (InterruptedException | ExcecutionException e) {
// Program will shutdown
}
}
(You should have noticed that because of the InterruptionException that must be caught - it indicates that there is some blocking, long running operation going on).
This also renders the execution service useless. If the code that submits a task to the executor always waits for the task to complete, there is no need to execute this task via executor. Instead, the submitting code should call the service directly.
So I assume that blocking is not inteded in this case. Probably your run method should look something like that:
public static void run(Service callableService) {
executor.submit(() -> {
Service result = callableService.call();
run(result.restart());
return result;
});
}
This code snippet is just basic, you might want to extend it to handle exceptional situations.
Is this kind of handling failures correct or efficient? That depends on context of application and how you are using error handling.
May encounter situation where I/O failures etc. are not handled properly.
Looks like you are already using Adapter type design pattern. Look at Adapter design pattern http://www.oodesign.com/adapter-pattern.html
I wrote an android app for killing background running processes which is performed in a background thread. And I use below class to create my own simple thread framework.
public final class ThreadPool {
private static final ExecutorService sES = Executors.newCachedThreadPool();
public static Future<?> runNow(Runnable task) {
return sES.submit(task);
}
}
However, a serious problem occured. That is the exception(unchecked exception) would be consumed by Executor framework quitely. So I don't know why the ActivityManager.killBackgroundProcesses() method does not work. After spending 2 or 3 hours and I wrote some log at almost every method invoke point, I found this method requires android.permission.KILL_BACKGROUND_PROCESSES permission, otherwise, it would throw a SecurityException that is an unchecked exception. The key is this exception is consumed by Excecutor framework, so I cannot see any exception information at logcat and the app does not crash at all and runs weird.
Of course, I don't know that at first, so I spent a lot of time to find out that reason, mainly depending on two posts:
Handling exceptions from Java ExecutorService tasks and
Catching thread exceptions from Java ExecutorService
So I changed the my ThreadPool class as:
public final class ThreadPool {
private static final ExecutorService sES = Executors.newCachedThreadPool();
/*
* submit(Runnable) and execute(Runnable) method has
* big difference. Especially in Exception handling!!!
* You have to pay attention.
*/
public static Future<?> submitNow(Runnable task) {
return sES.submit(task);
}
public static void executeNow(Runnable task) {
sES.execute(task);
}
}
But I still have below question:
Why Sun/Oracle decide to consume the exception instead of transfer to users to handle if submit(Runnable command) method is used?
How can I change this behavior to handle unchecked exception according to my own need if I insist using submit() method?
And my doubts are:
If submit(Runnable command) method is used, I know the exception result can be get by Future.get() method. But, if we use Future.get() method to judge if an exception occured, the thread Future object located in would be block. That is not what we expect in most case, I suppose.
I also learned Executor.execute() method handles exception like common Thread.start(). But there is no return value. So the task cannot be shut down at any time. Users have no ability to shut down any running thread by Future.cancel() method when leaving activity.
If you call get() on the future, you will get an ExecutionException if the underlying operation (callable) threw an exception. See the docs.
You can't change this behavior (from point 1. )
The reason why this is implemented this way is the following: submit is a non blocking call. The job gets posted in the executor and executed at a later time.
Only when the job is executed do you know if it crashed or not, so only when you try to access the result of the job do you get the exception.
Finally, I find a good solution.
We can extend Thread and invoke setUncaughtHandler() in the constructor like below.
public class MyThread1 extends Thread {
public MyThread1(Runnable task) {
super(task);
setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("thread throws an uncaught exception at thread id: " + t.getId());
}
});
}
}
And then customize a ThreadFactory like following.
public class MyThreadFactory1 implements ThreadFactory {
#Override
public Thread newThread(Runnable r) {
return new MyThread1(r, "Peace");
}
}
So we can call the factory method in Executors like following.
ExecutorService es = Executors.newSingleThreadExecutor(new MyThreadFactory1());
So we can detect the uncaught exception happened in thread.
In a threaded environment, unchecked exceptions are known to be notorious and weird behaviors could occur like threads dying, no exception log etc.
One good way is to wrap the runnable object in a thread. Create a thread group and add the thread to the thread group.
final ThreadGroup group = new ThreadGroup("<a name for the thread group>");
public static Future<?> submitNow(Runnable task) {
//Create a thread wrapping the runnable task and specify the thread group
Thread t = new Thread(group,task);
return sES.submit(task);
}
The ThreadGroup class has its uncaughtException(Thread, Throwable) method which is automatically called by the JVM if a thread encountered an exception and is uncaught in your code. See http://developer.android.com/reference/java/lang/ThreadGroup.html
You can also change the behavior by creating your own ThreadGroup object and overriding the uncaughtException method:
public class MyThreadGroup extends ThreadGroup {
#Override
public void uncaughtException(Thread t, Throwable e) {
//do what you need to do to handle the exception
}
}
Or you can assign an UncaughtExceptionHandler to the current Thread.
public class MyUncaughtExceptionHandler implements UncaughtExceptionHandler {
#Override
public void uncaughtException(Thread t, Throwable t2) {
//Implement
}
}
Thread.currentThread().setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
Or set the default exception handler:
Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
In server side, I created One Non stopping thread ( infinite while loop using in run method) that name as Event extractor and it extends java Observable .
when i call notifyObservers method it works fine. but at some point the thread has been dead locked.
Does any one help me out to resolve this problem. I have shared the codes below
public class EventExtractor extends Observable implements Runnable {
#Override
public void run() {
while (true) {
try {
Thread.sleep(NOTIFY_DELAY); // 60000 milliseconds
} catch (InterruptedException e) {
Logs.error("InterruptedException in run() in Extractor",e);
}
Set<String> productSet= getProductSet();
this.setChanged();
/* notify the products to observer */
this.notifyObservers(productSet);
/* clear the set to maintain the products again for a minute */
Set<String> productSets= getProductSet();
if (productsSets != null) {
productsSet.clear();
}
}
}
}
public class FMListener implements Observer{
public void update(Observable arg0, Object arg1) {
Set<String> set = (Set<String>) arg1;
for (String ProductID: set) {
LOGS.debug("***** obj is:::: " + ProductID);
//call Http request calls to particular product and update into data base
httpClient.sendRequest(***URL**);
}
}
getProductSet() is a static method to add products when receive event from the product
What makes you think it is a "Dead Lock". Have you try to do thread dump when you think it is in "dead lock" and found the main thread waiting for something?
The reason I doubt it is actually a dead lock is, there is no obvious locking happening, AND, most importantly, Java's Observer logic doesn't spawn any new thread: the logic of observers are simply running within your caller thread context, which means, there is NO other thread in your situation, hence, just by the logic above, there is no reason to have dead lock
It may be the HTTP Client you are using is not thread-safe and there is someone else using it. However I think it is more likely to be some uncaught exception (maybe from your observer logic) makes your EventExtractor thread die.
Suppose that I have a method which spawns a new thread and do some work. Under certain conditions, the newly spawn thread would throw a certain type of exception, which terminates the entire process. I would like to write JUnit tests to verify this behavior. Is there a way to do it?
The method is:
private void foo() {
new Thread() {
#Override void run() {
throw new CertainException("exception messages");
}
}.start();
}
In test (conceptually):
public testExceptionThrownFromNewThread() throws Exception {
try {
foo();
Thread.sleep(5000); // wait for the exception to be thrown
fail();
} catch (CertainException e) {
assertEquals(e.message, "exception messages");
}
}
This test doesn't work because the exception spawn from the other thread cannot be caught.
If you want to test just the code inside of the run() method, refactor it ouf of the foo() method (probably into a Runnable) and test it separately without running it from a thread.
private void foo() {
new Thread(new MyRunnable()).start();
}
public class MyRunnable implements Runnable {
public void run() {
....
}
}
Now you can instantiate a MyRunnable object and call the run() method from your test without needing to start a thread.
EDIT
Testing of the thread creation could be done by using a ThreadFactory Mock. (as Jon Skeet pointed out).
You could overwrite the default UncaughtExceptionHandler for Threads. It gets called whenever a Thread throws an exception. In this handler, you can check whether the expected exception is equal to the thrown exception and e.g. test for messages or count the occurences of the exception. By using a CountDownLatch, you can also check whether the exceptions are thrown in time and how many of them you expect.
This works even if you do not have access to the Thread created by the class under test. If you have access to it though, there is certainly an easier approach, e.g. refactoring the class under test and introduce an Exception Listener or alike. Make the class under test better testable also improves the design, e.g. by removing the dependency on Threads and directly test the body of the run() method which you could externalize.
public class ThreadExceptionTest {
private void foo() {
new Thread(new Runnable() {
#Override
public void run() {
throw new RuntimeException("exception messages");
}
}).start();
}
#Test
public void testFoo() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
final RuntimeException expectedException = new RuntimeException("exception messages");
UncaughtExceptionHandler eh = new UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread t, Throwable e) {
if (e.getMessage().equals(expectedException.getMessage()))
latch.countDown();
}
};
Thread.setDefaultUncaughtExceptionHandler(eh);
foo();
assertTrue(latch.await(100,TimeUnit.MILLISECONDS));
}
}
Well, unit tests are supposed to verify results of method calls, not implementation details.
In your library, if thread terminates, how does it affect library user? Maybe computations won't be finished and end results won't be recored in database? Then check database. Maybe thread will stop doing some periodic tasks (like cleanup)? Then check whether cleanup is still being done.
And if exception thrown won't affect user in any way, then there's nothing to check. Because whether exception is thrown or not is just an implementation details (user will never see it).
One option is to make the capability to start a thread a dependency - which you can specify using the existing ThreadFactory interface. Then in your unit test you can provide a specialist ThreadFactory which wraps the given Runnable in order to record exceptions etc.
You'll be able to test that:
The ThreadFactory was used
The thread was started
The operation threw an exception