How unit test multithreaded Android RxJava - java

Suppose there is a button.
Clicking the button disables it (mainThread thread), starts a background task to load data (IO thread). Once data is loaded, the button is enabled back (mainThread thread).
For test, it's common to change schedulers to immediate, but this won't work in my case - button click will block until completion of background task, I'll never be able to check if the button was disabled after it started background task.
Besides unit tests, I'd also like to test this in functional Espresso tests.
How do I test this multithreaded RxJava case?

You can write your own ThreadFactory
ThreadFactory custom = new CustomThreadFactory();
ExecutorService executorService = Executors.newCachedThreadPool(custom); //or use newSingleThreadExecutor(..)
Scheduler customScheduler = Schedulers.from(executorService);
now you can use this scheduler and not block the main queue plus getting called when a new thread is needed:
class CustomThreadFactory implements ThreadFactory {
public Thread lastT;
public int newThreadCounter = 0;
#Override
public Thread newThread(Runnable r) {
newThreadCounter++;
System.out.println("newThread called");
Thread lastT = new Thread(r); //or CustomThread(r)
return lastT;
}
}
You can even go further and instrument the new Thread -
class CustomThread extends Thread {
public CustomThread(Runnable r) {
super(r);
}
#Override
public void run() {
System.out.printf("About to run!");
super.run();
}
}
}

I suggest you to use RxUtil
1). Provide default implementation of RxUtil through the constructor or DI
2). When you create your observable, instead of applying schedulers directly:
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
Use RxUtil:
.compose(rxUtil.applySchedulers())
Example:
https://github.com/DAYTeam/GoEnglish/blob/master/app/src/main/java/ru/goenglish/goenglish/services/impl/ScheduleServiceImpl.java#L38-L44
3). In unit tests, instead of default implementation of RxUtil, create mocked version:
public class UnitTestRxUtil implements RxUtil {
#Override
public <T> Observable.Transformer<T, T> applySchedulers() {
return observable -> observable.subscribeOn(Schedulers.immediate())
.observeOn(Schedulers.immediate());
}
}
link: https://github.com/DAYTeam/GoEnglish/blob/master/app/src/test/java/ru/goenglish/goenglish/util/UnitTestRxUtil.java
4). Pass this implementation through the constructor, or DI.
Example (constructor): https://github.com/DAYTeam/GoEnglish/blob/master/app/src/test/java/ru/goenglish/goenglish/ScheduleServiceImplTest.java#L45
As a result, all the tests, will be executed in one thread, and in the application, it will be executed on different executors

Related

When the cache is not defined, does HystrixCommand definitely execute `run` or `fallback`

I need to wait synchronously for some logic of the HystrixCommand to finish, so I added a CountDownLatch and released it in run and fallback.
public class AsyncHystrixCommand extends HystrixCommand implements SofaHystrixInvokable {
#Override
protected Object run() throws Exception {
// part1 sync
this.syncCall();
lock.countDown();
// part2 async
return this.asyncCall();
}
#Override
protected Object getFallback() {
if (lock.getCount() > 0) {
lock.countDown();
}
}
}
Then the main thread will be blocking via lock.wait, but if run or fallback is not executed, this will wait forever.
In the flowchart of Hystrix, if cache is not defined, can Hystrix guarantee that run or fallback will be executed? Is there any better way?
HystrixCommand works asynchronously using RxJava 1.x, but it supports synchronous execution.
All you need to do is just calling execute() method with your command like below.
Object result = new YourHystrixCommand().execute()`
Or you can wait with Future or Observable by yourself in case of using queue() or observe().

How to do Unit Testing for asynchronous calls?

I want to do Unit Tests for asynchronous methods in android. The result needs to be a "notified by observer's callback". Have a look at the below example. How can I write a unit test case for doSomething() method?
public interface IFooObserver {
void onResult(String result);
}
public class Foo {
private IFooObserver mObserver;
public Foo(IFooObserver observer) {
mObserver = observer;
}
public void doSomething() {
new Thread(new Runnable() {
#Override
public void run() {
// do something..
mObserver.onResult("hello, world!");
}
}).start();
}
}
Simply: don't use "bare metal" threads.
Use ExecutorServices instead - because that allows you to use dependency injection to turn your multi-threaded code into a single-threaded thing for testing - using a Same Thread Executor Service.
Example:
class Whatever {
private final ExecutorService service;
Whatever() { this ( Executors.newSingleThreadExecutor() ); }
Whatever(ExecutorService service) { this.service = service; }
void foo() {
service.submit ( ... whatever
The point is: when you are using a thread directly, you have no control whatsoever there. Most likely, that will lead to test cases that need complicated signaling, or worse: rely on calling sleep() here or there. And that is always bad - it increases the execution time of your tests; or, worse, you get the timing wrong; and occasionally your tests fail during regression. Because of different load on your test system; and threads showing different runtime characteristics.
So, long story short: if possible, avoid using threads directly; instead use the aforementioned concept to simply avoid multiple threads for testing.

ThreadFactory and newThread(Runnable r) how to access to the attributes of r if it is a Thread?

For my thesis I'm working on a Discrete Event System Simulator. The simulation consists in a set of SimulatorThread extends Thread whose action consist in scheduling Events to the Simulator. Each SimulatorThread interracts with the Simulator through the SimulatorInterface.
public abstract class SimulatorThread extends Thread {
private SimulatorInterface si;
public SimulatorThread(SimulatorInterface si) {
this.si = si;
}
...
}
public final class Simulator {
private ExecutorService exec;
...
public void assignThread(SimulatorThread... stList) {
...
}
}
Before the simulation begins, each SimulatorThread is assigned to the Simulator, then the Simulator will execute each thread through exec.execute(simulatorThread). My problem is that in some part of the code i need to get a reference to the current running SimulatorThread, but the instruction (SimulatorThread) Thread.currentThread() gives a cast execption. Infact the output of System.out.print(Thread.currentThread().getClass()) is class java.lang.Thread, but I would like that the output is class SimulatorThread which can be obtained by running the thread using the instruction simulatorThread.start() instead of using the executor. So I thought that the problem is in writing an ad-hoc ThreadFactory that return an instance of SimulatorThread.
Infact I tried to use the trivial SimulatorThreadFactory extends ThreadFactory:
public class SimulatorThreadFactory implements ThreadFactory {
#Override
public Thread newThread(Runnable r) {
return new SimulatorThread(new SimulatorInterface());
}
}
and with this I obtained the previously cited output 'class SimulatorThread'. The problem is that when I call 'exec.execute(simulatorThread)', the parameter has an attribute 'SimulatorInterface' to which I need to get access, but I can't becaues the parameter of the method 'newThread' is a 'Runnable'. I expose here a wrong code that I hope expresses what I mean better than how I explain in words:
public class SimulatorThreadFactory implements ThreadFactory {
#Override
public Thread newThread(Runnable r) {
SimulatorInterface si = r.getSimulatorInterface(); // this is what
// I would like
// the thread factory
// to do
return new SimulatorThread(si);
}
}
So, how can I access to attribute 'SimulatorInterface' of the 'SimulatorThread' inside the method newThread in order to create a SimulatorThread if its paramater is a Runnable?
If I understand your needs, the right way to do this is to not extend Thread but to implement Runnable. Then all of the benefits of your own class hierarchy can be enjoyed:
public abstract class SimulatorRunnable extends Runnable {
protected SimulatorInterface si;
public SimulatorRunnable(SimulatorInterface si) {
this.si = si;
}
}
public final class Simulator extends SimulatorRunnable {
public Simulator(SimulatorInterface si) {
super(si);
}
public void run() {
// here you can use the si
si.simulate(...);
}
}
Then you submit your simulator to your thread-pool:
Simulator simulator = new Simulator(si);
...
exec.submit(simulator);
My problem is that in some part of the code i need to get a reference to the current running SimulatorThread, but the instruction (SimulatorThread) Thread.currentThread() gives a cast execption
You should not be passing a Thread into an ExecutorService. It is just using it as a Runnable (since Thread implements Runnable) and the thread-pool starts its' own threads and will never call start() on your SimulatorThread. If you are extending Thread then you need to call thread.start() directly and not submit it to an ExecutorService. The above pattern of implements Runnable with an ExecutorService is better.
#Gray's answer is correct, pointing out that the ExecutorService is designed to use its own threads to execute your Runnables, and sometimes created threads will even be reused to run different Runnables.
Trying to get information from (SimulatorThread) Thread.currentThread() smells like a 'global variable' anti-pattern. Better to pass the 'si' variable along in method calls.
If you really want global variables that are thread-safe, use ThreadLocals:
public final class Simulator extends SimulatorRunnable {
public static final ThreadLocal<SimulatorInterface> currentSim = new ThreadLocal<>();
public Simulator(SimulatorInterface si) {
super(si);
}
public void run() {
currentSim.set(si)
try{
doStuff();
}
finally{
currentSim.unset();
}
}
private void doStuff()
{
SimulatorInterface si = Simulator.currentSim.get();
//....
}
}

Thread creation listener

Is it possible to write Thread creation listener in java? For example using aop?!
I mean something like this that if my application creates a thread I would like to register this object in my own table, container or something.
I would create a thread that continously lists all running threads on the JVM.
Then each time it noticies that a new thread has appeared, it would notify in either way a class in your code.
Here are some links about how to list all threads currently running on the JVM :
Get a List of all Threads currently running in Java
Listing All Running Threads
============
A starting code :
ThreadCreationListener.java
public interface ThreadCreationListener {
public void onThreadCreation(Thread newThread);
}
ThreadCreationMonitor.java
public class ThreadCreationMonitor extends Thread {
private List<ThreadCreationListener> listeners;
private boolean canGo;
public ThreadCreationMonitor() {
listeners = new Vector<ThreadCreationListener>();//Vector class is used because many threads may use a ThreadCreationMonitor instance.
canGo = true;
// Initialize the rest of the class here...
}
// Most important methods
public void addListener(ThreadCreationListener tcl) {
listeners.add(tcl);
}
public void removeListener(ThreadCreationListener tcl) {
listeners.remove(tcl);
}
public void run() {
List<Thread> runningThreads;
List<Thread> lastRunningThreads = new ArrayList<>();
while(canGo) {
// Step 1 - List all running threads (see previous links)
// runningThreads = ...
// Step 2 - Check for new threads and notify all listeners if necessary
if (runningThreads.removeAll(lastRunningThreads)==true) {
for(Thread t : runningThreads) {
for(ThreadCreationListener tcl : listeners) {
lastRunningThreads.add(t);
tcl.onThreadCreation(t); //Notify listener
}
}
}
}
}
public void shutdown() {
canGo = false;
}
}
MyThreadInfoConsumer.java
public class MyThreadInfoConsumer implements ThreadCreationListener {
public void onThreadCreation(Thread newThread) {
// Process here the notification...
}
}
Main.java
public class Main {
public static void main(String[] args) {
ThreadCreationMonitor tcm = new ThreadCreationMonitor();
tcm.start();
MyThreadInfoConsumer myTIC = new MyThreadInfoConsumer();
tcm.addListener(myTIC);
// rest of your code...
// Don't forget to call tcm.shutdown() when exiting your application !
}
}
I think this would be possible with AOP (aspectj for instance). But it is still required to create your own Thread and ThreadGroup/Executor types, unless you can recompile the JDK classes with the aspect compiler. Define the pointcut on your thread's start method if you want to register on thread launching or on the createThread of your pool if you want to register on the creation of the thread objects.
The following works only if you recompiled the JDK with the aspect compiler:
All threads are started with Thread.start, so write a pointcut for that method then you can use advices to do what you'd like to. Of course this is not perfect since e.g. a cachedThreadPool executor might not start a new thread for each task, but maybe if you register a pointcut on Runnable.run and Callable.call rather than on Thread.start, that might be sufficient enough.
Perhaps a ThreadGroup is what you need. All Threads are members of a ThreadGroup and when you start a new Thread it is added to the same group as its parent by default.
In theory its possible (but not recommended) to sub-class to be notified when a Thread is added or removed from the group.
It is likely that polling the threads of this groups, or polling all threads is a better solution.

How to run a Listener in a different thread or do its calculation in a different thread

I'm trying to build a cache with Google Guava and want to do some calculation on the expired objects. A removalListener notifies me, if some object was removed.
How can I run the removalListener in a different thread than the main application or pass the expired object (in the simple example below, that would be the Integer 3) to a different thread that handles the calculation?
Edit: As the calculation is rather short, but happens often, I would rather not create a new thread each time (would be thousands of threads), but have one (or maybe two) who calculate all objects.
Simple example:
Cache<String, Integer> cache = CacheBuilder.newBuilder().maximumSize(100)
.expireAfterAccess(100, TimeUnit.NANOSECONDS)
.removalListener(new RemovalListener<String, Integer>() {
public void onRemoval(final RemovalNotification notification) {
if (notification.getCause() == RemovalCause.EXPIRED) {
System.out.println("removed " + notification.getValue());
// do calculation=> this should be in another thread
}
}
})
.build();
cache.put("test1", 3);
cache.cleanUp();
To run your listener in an executor, wrap it with RemovalListeners.asynchronous.
.removalListener(asynchronous(new RemovalListener() { ... }, executor))
Create an ExecutorService using one of the Executors factory methods, and submit a new Runnable to this executor each time you need to:
private ExecutorService executor = Executors.newSingleThreadExecutor();
...
public void onRemoval(final RemovalNotification notification) {
if (notification.getCause() == RemovalCause.EXPIRED) {
System.out.println("removed " + notification.getValue());
submitCalculation(notification.getValue());
}
}
private void submitCalculation(final Integer value) {
Runnable task = new Runnable() {
#Override
public void run() {
// call your calculation here
}
};
executor.submit(task);
}
You can create a new class, and implement the java.utils.Runnable interface like so;
public class MyWorkerThread implements Runnable {
public MyWorkerThread(/*params*/) {
//set your instance variables here
//then start the thread
(new Thread(this)).start();
}
public void run() {
//do useful things
}
}
When you create a new MyWorkerThread by calling the constructor, execution is returned to the calling code as soon as the constructor is finished, and a separate thread is started that runs the code inside the run() method.
If you might want to create MyWorkerThread objects without immediately starting them off, you can remove the Thread.start() code from the constructor, and call the thread manually from the instance later like so;
MyWorkerThread t = new MyWorkerThread();
//later
(new Thread(t)).start();
Or if you want to keep a reference to the Thread object so you can do groovy things like interrupt and join, do it like so;
Thread myThread = new Thread(t);
myThread.start();
//some other time
myThread.interrupt();
you can simply create intermediate queue for expired entities (expiration listener will just add expired object to this queue) - say some sort of blocking in-memory queue - ArrayBlockingQueue, LinkedBlockingDeque.
Then you can setup thread-pool and handlers(with configurable size) that will consume objects using poll() method.
For high-performance queue - i can advice more advanced non-blocking queue implementation if needed. also you can read more about high-performance non-blocking queues here Add the first element to a ConcurrentLinkedQueue atomically
Use an executor service to dispatch your task to a different thread.
ExecutorService have an internal blocking queue that is used for safe publishing of references between the producer and the consumer threads. The factory class Executors can be used to create different ExecutorService with different thread management strategies.
private ExecutorService cleanupExecutor = Executors.newFixedThreadPool(CLEANUP_THREADPOOL_SIZE);
...
public void onRemoval(final RemovalNotification notification) {
if (notification.getCause() == RemovalCause.EXPIRED) {
System.out.println("removed " + notification.getValue());
doAsyncCalculation(notification.getValue());
}
}
private void doAsyncCalculation(final Object obj) {
cleanupExecutor.submit(new Runnable() {
public void run() {
expensiveOperation(obj);
}
}
}
In doAsyncCalculation you are creating new tasks to be run but not new threads. The executor service takes care of dispatching the task to the threads in the executorService's associated thread pool.

Categories