3

I'm using following to get a ExecutorService for my subscriptions:

public static ExecutorService getThreadPoolExecutorService(int threads)
{
    int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();
    ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
            NUMBER_OF_CORES * 2,
            NUMBER_OF_CORES * 2,
            60L,
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<Runnable>()
    );
    return Executors.newFixedThreadPool(threads, threadPoolExecutor.getThreadFactory());
}

And use it like following:

public static Scheduler getBackgroundSchedular()
{
    if (mBackgroundExecutorService == null)
        mBackgroundExecutorService = ThreadUtil.getThreadPoolExecutorService(4);
    return Schedulers.from(mBackgroundExecutorService);
}

And I use this schedular for my observables that should run in the background.

Question

How to use a PriorityBlockingQueue for RXJava? Normally I would use some special runnables that implement a compare function and use the corresponding compare function for the PriorityBlockingQueue and replace the LinkedBlockingQueue in the example above with the PriorityBlockingQueue, but how can I do this with RXJava observables?

prom85
  • 16,896
  • 17
  • 122
  • 242

1 Answers1

3

Schedulers in RxJava are orthogonal to the datastream and don't know about them at all. All they do is execute a Runnable instance and all Runnables created by operators are born equal. Thus, it doesn't make sense to use priority queues with Schedulers.

In addition, datastreams are sequential and unless there is some boundary like thread swap, they maintain their ordering. Unless you collect the events and do the ordering manually, there is just a probability an operator with a priority queue will reorder data as you expect.

Edit

A bit unconventional, but you could also lay the PriorityBlockingQueue across a subject and some operators so you can feed a sequence with tasks:

PriorityBlockingQueue<Task> q = ...

Subject<Integer, Integer> subject = PublishSubject.<Integer>create().toSerialized();

subject
.map(v -> q.poll())
.doOnNext(v -> v.execute())
.subscribe();

q.offer(new Task(...));
subject.onNext(1);
akarnokd
  • 69,132
  • 14
  • 157
  • 192
  • Consider following example: I have one subscriber that loads all folders and there contents from the sd card. I already display the folders as soon as I know their name, the observable will continue it's work in the background though. When I click an unloaded folder I create a second observable that only loads this single folders content => I want this thread to have higher priority than the main observables thread. Unsubscribing the main observable is an option, but I need the data from it anyway, so unsubscribing is not the best option... – prom85 Feb 22 '16 at 12:42
  • What's wrong with using the IO scheduler to run that single directory and let the OS arbitrate? – akarnokd Feb 22 '16 at 13:13
  • I can see significant speed improvements when I first unsubscribe the main observable... I wanted to check if a higher priority for the single folder observable has the same effect... – prom85 Feb 22 '16 at 13:15