/* == This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2014, Enno Gottschalk <mrmaffen@googlemail.com>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
package org.tomahawk.tomahawk_android.utils;
import org.tomahawk.libtomahawk.resolver.Query;
import org.tomahawk.tomahawk_android.mediaplayers.TomahawkMediaPlayer;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ThreadManager {
/*
* Gets the number of available cores
* (not always the same as the maximum number of cores)
*/
private static final int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();
// Sets the amount of time an idle thread waits before terminating
private static final int KEEP_ALIVE_TIME = 1;
// Sets the Time Unit to seconds
private static final TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;
private static class Holder {
private static final ThreadManager instance = new ThreadManager();
}
private final ThreadPoolExecutor mThreadPool;
private final ConcurrentHashMap<TomahawkMediaPlayer, ThreadPoolExecutor> mPlaybackThreadPools
= new ConcurrentHashMap<>();
private final Map<Query, Collection<TomahawkRunnable>> mQueryRunnableMap;
private ThreadManager() {
mQueryRunnableMap = new ConcurrentHashMap<>();
mThreadPool = new ThreadPoolExecutor(NUMBER_OF_CORES, NUMBER_OF_CORES,
KEEP_ALIVE_TIME, KEEP_ALIVE_TIME_UNIT, new PriorityBlockingQueue<Runnable>());
}
public static ThreadManager get() {
return Holder.instance;
}
public void execute(TomahawkRunnable r) {
mThreadPool.execute(r);
}
public void execute(TomahawkRunnable r, Query query) {
Collection<TomahawkRunnable> runnables = mQueryRunnableMap.get(query);
if (runnables == null) {
runnables = new HashSet<>();
}
runnables.add(r);
mQueryRunnableMap.put(query, runnables);
mThreadPool.execute(r);
}
public boolean stop(Query query) {
boolean success = false;
Collection<TomahawkRunnable> runnables = mQueryRunnableMap.remove(query);
if (runnables != null) {
for (TomahawkRunnable r : runnables) {
mThreadPool.remove(r);
success = true;
}
}
return success;
}
public void executePlayback(TomahawkMediaPlayer mp, Runnable r) {
ThreadPoolExecutor pool = mPlaybackThreadPools.get(mp);
if (pool == null) {
pool = new ThreadPoolExecutor(1, 1, KEEP_ALIVE_TIME,
KEEP_ALIVE_TIME_UNIT, new LinkedBlockingQueue<Runnable>());
mPlaybackThreadPools.put(mp, pool);
}
pool.execute(r);
}
public boolean isActive() {
for (ThreadPoolExecutor pool : mPlaybackThreadPools.values()) {
if (pool.getActiveCount() > 0 || pool.getQueue().size() > 0) {
return true;
}
}
return mThreadPool.getActiveCount() > 0 || mThreadPool.getQueue().size() > 0;
}
}