new Thread(new Runnable() { @Override public void run() { //作一些任務 } }).start();
public class App extends Application{ private static App instance; private PoolThread executor; public static synchronized App getInstance() { if (null == instance) { instance = new App(); } return instance; } public App(){} @Override public void onCreate() { super.onCreate(); instance = this; //初始化線程池管理器 initThreadPool(); } /** * 初始化線程池管理器 */ private void initThreadPool() { // 建立一個獨立的實例進行使用 executor = PoolThread.ThreadBuilder .createFixed(5) .setPriority(Thread.MAX_PRIORITY) .setCallback(new LogCallback()) .build(); } /** * 獲取線程池管理器對象,統一的管理器維護全部的線程池 * @return executor對象 */ public PoolThread getExecutor(){ return executor; } } //自定義回調監聽callback,能夠全局設置,也能夠單獨設置。都行 public class LogCallback implements ThreadCallback { private final String TAG = "LogCallback"; @Override public void onError(String name, Throwable t) { Log.e(TAG, "LogCallback"+"------onError"+"-----"+name+"----"+Thread.currentThread()+"----"+t.getMessage()); } @Override public void onCompleted(String name) { Log.e(TAG, "LogCallback"+"------onCompleted"+"-----"+name+"----"+Thread.currentThread()); } @Override public void onStart(String name) { Log.e(TAG, "LogCallback"+"------onStart"+"-----"+name+"----"+Thread.currentThread()); } }
PoolThread executor = App.getInstance().getExecutor(); executor.setName("最簡單的線程調用方式"); executor.setDeliver(new AndroidDeliver()); executor.execute(new Runnable() { @Override public void run() { Log.e("MainActivity","最簡單的線程調用方式"); } });
PoolThread executor = App.getInstance().getExecutor(); executor.setName("異步回調"); executor.setDelay(2,TimeUnit.MILLISECONDS); // 啓動異步任務 executor.async(new Callable<Login>(){ @Override public Login call() throws Exception { // 作一些操做 return null; } }, new AsyncCallback<Login>() { @Override public void onSuccess(Login user) { Log.e("AsyncCallback","成功"); } @Override public void onFailed(Throwable t) { Log.e("AsyncCallback","失敗"); } @Override public void onStart(String threadName) { Log.e("AsyncCallback","開始"); } });
public interface Runnable { public void run(); } public interface Callable<V> { V call() throws Exception; }
public final class RunnableWrapper implements Runnable { private String name; private CallbackDelegate delegate; private Runnable runnable; private Callable callable; public RunnableWrapper(ThreadConfigs configs) { this.name = configs.name; this.delegate = new CallbackDelegate(configs.callback, configs.deliver, configs.asyncCallback); } /** * 啓動異步任務,普通的 * @param runnable runnable * @return 對象 */ public RunnableWrapper setRunnable(Runnable runnable) { this.runnable = runnable; return this; } /** * 異步任務,回調用於接收可調用任務的結果 * @param callable callable * @return 對象 */ public RunnableWrapper setCallable(Callable callable) { this.callable = callable; return this; } /** * 自定義xxRunnable繼承Runnable,實現run方法 * 詳細能夠看個人GitHub:https://github.com/yangchong211 */ @Override public void run() { Thread current = Thread.currentThread(); ThreadToolUtils.resetThread(current, name, delegate); //開始 delegate.onStart(name); //注意須要判斷runnable,callable非空 // avoid NullPointException if (runnable != null) { runnable.run(); } else if (callable != null) { try { Object result = callable.call(); //監聽成功 delegate.onSuccess(result); } catch (Exception e) { //監聽異常 delegate.onError(name, e); } } //監聽完成 delegate.onCompleted(name); } }
public final class CallableWrapper<T> implements Callable<T> { private String name; private ThreadCallback callback; private Callable<T> proxy; /** * 構造方法 * @param configs thread配置,主要參數有:線程name,延遲time,回調callback,異步callback * @param proxy 線程優先級 */ public CallableWrapper(ThreadConfigs configs, Callable<T> proxy) { this.name = configs.name; this.proxy = proxy; this.callback = new CallbackDelegate(configs.callback, configs.deliver, configs.asyncCallback); } /** * 詳細能夠看個人GitHub:https://github.com/yangchong211 * 自定義Callable繼承Callable<T>類,Callable 是在 JDK1.5 增長的。 * Callable 的 call() 方法能夠返回值和拋出異常 * @return 泛型 * @throws Exception 異常 */ @Override public T call() { ThreadToolUtils.resetThread(Thread.currentThread(),name,callback); if (callback != null) { //開始 callback.onStart(name); } T t = null; try { t = proxy == null ? null : proxy.call(); } catch (Exception e) { e.printStackTrace(); //異常錯誤 if(callback!=null){ callback.onError(name,e); } }finally { //完成 if (callback != null) { callback.onCompleted(name); } } return t; } }
/** * <pre> * @author 楊充 * blog https://www.jianshu.com/p/53017c3fc75d * time * desc 異步callback回調接口 * revise * GitHub https://github.com/yangchong211 * </pre> */ public interface AsyncCallback<T> { /** * 成功時調用 * @param t 泛型 */ void onSuccess(T t); /** * 異常時調用 * @param t 異常 */ void onFailed(Throwable t); /** * 通知用戶任務開始運行 * @param threadName 正在運行線程的名字 */ void onStart(String threadName); }
/** * <pre> * @author: yangchong * blog : https://github.com/yangchong211 * time : * desc : 一個回調接口,用於通知用戶任務的狀態回調委託類 * 線程的名字能夠自定義 * revise: * </pre> */ public interface ThreadCallback { /** * 當線程發生錯誤時,將調用此方法。 * @param threadName 正在運行線程的名字 * @param t 異常 */ void onError(String threadName, Throwable t); /** * 通知用戶知道它已經完成 * @param threadName 正在運行線程的名字 */ void onCompleted(String threadName); /** * 通知用戶任務開始運行 * @param threadName 正在運行線程的名字 */ void onStart(String threadName); }
public final class ThreadConfigs { /** * 線程的名稱 * 經過setName方法設置 */ public String name; /** * 線程執行延遲的時間 * 經過setDelay方法設置 */ public long delay; /** * 線程執行者 * JAVA或者ANDROID */ public Executor deliver; /** * 用戶任務的狀態回調callback */ public ThreadCallback callback; /** * 異步callback回調callback */ public AsyncCallback asyncCallback; }
public final class ThreadToolUtils { /** * 標誌:是否在android平臺上 */ public static boolean isAndroid; /* * 靜態代碼塊 * 判斷是不是android環境 * Class.forName(xxx.xx.xx) 返回的是一個類對象 * 首先要明白在java裏面任何class都要裝載在虛擬機上才能運行。 */ static { try { Class.forName("android.os.Build"); isAndroid = true; } catch (Exception e) { isAndroid = false; } } }
public final class PoolThread implements Executor{ /** * 啓動任務 * 這個是實現接口Executor中的execute方法 * 提交任務無返回值 * @param runnable task,注意添加非空註解 */ @Override public void execute (@NonNull Runnable runnable) { //獲取線程thread配置信息 ThreadConfigs configs = getLocalConfigs(); //設置runnable任務 runnable = new RunnableWrapper(configs).setRunnable(runnable); //啓動任務 DelayTaskDispatcher.get().postDelay(configs.delay, pool, runnable); //重置線程Thread配置 resetLocalConfigs(); } /** * 當啓動任務或者發射任務以後須要調用該方法 * 重置本地配置,置null */ private synchronized void resetLocalConfigs() { local.set(null); } /** * 注意須要用synchronized修飾,解決了多線程的安全問題 * 獲取本地配置參數 * @return */ private synchronized ThreadConfigs getLocalConfigs() { ThreadConfigs configs = local.get(); if (configs == null) { configs = new ThreadConfigs(); configs.name = defName; configs.callback = defCallback; configs.deliver = defDeliver; local.set(configs); } return configs; } }
public final class PoolThread implements Executor{ //省略部分代碼…… public static class ThreadBuilder { final static int TYPE_CACHE = 0; final static int TYPE_FIXED = 1; final static int TYPE_SINGLE = 2; final static int TYPE_SCHEDULED = 3; int type; int size; int priority = Thread.NORM_PRIORITY; String name; ThreadCallback callback; Executor deliver; ExecutorService pool; private ThreadBuilder(int size, int type, ExecutorService pool) { this.size = Math.max(1, size); this.type = type; this.pool = pool; } /** * 經過Executors.newSingleThreadExecutor()建立線程池 * 內部只有一個核心線程,全部任務進來都要排隊按順序執行 */ public static ThreadBuilder create(ExecutorService pool) { return new ThreadBuilder(1, TYPE_SINGLE, pool); } /** * 經過Executors.newCachedThreadPool()建立線程池 * 它是一個數量無限多的線程池,都是非核心線程,適合執行大量耗時小的任務 */ public static ThreadBuilder createCacheable() { return new ThreadBuilder(0, TYPE_CACHE, null); } /** * 經過Executors.newFixedThreadPool()建立線程池 * 線程數量固定的線程池,所有爲核心線程,響應較快,不用擔憂線程會被回收。 */ public static ThreadBuilder createFixed(int size) { return new ThreadBuilder(size, TYPE_FIXED, null); } /** * 經過Executors.newScheduledThreadPool()建立線程池 * 有數量固定的核心線程,且有數量無限多的非核心線程,適合用於執行定時任務和固定週期的重複任務 */ public static ThreadBuilder createScheduled(int size) { return new ThreadBuilder(size, TYPE_SCHEDULED, null); } /** * 經過Executors.newSingleThreadPool()建立線程池 * 內部只有一個核心線程,全部任務進來都要排隊按順序執行 * 和create區別是size數量 */ public static ThreadBuilder createSingle() { return new ThreadBuilder(0, TYPE_SINGLE, null); } /** * 將默認線程名設置爲「已使用」。 */ public ThreadBuilder setName (@NonNull String name) { if (name.length()>0) { this.name = name; } return this; } /** * 將默認線程優先級設置爲「已使用」。 */ public ThreadBuilder setPriority (int priority) { this.priority = priority; return this; } /** * 將默認線程回調設置爲「已使用」。 */ public ThreadBuilder setCallback (ThreadCallback callback) { this.callback = callback; return this; } /** * 設置默認線程交付使用 */ public ThreadBuilder setDeliver(Executor deliver) { this.deliver = deliver; return this; } /** * 建立用於某些配置的線程管理器。 * @return 對象 */ public PoolThread build () { //最大值 priority = Math.max(Thread.MIN_PRIORITY, priority); //最小值 priority = Math.min(Thread.MAX_PRIORITY, priority); size = Math.max(1, size); if (name==null || name.length()==0) { // 若是沒有設置名字,那麼就使用下面默認的線程名稱 switch (type) { case TYPE_CACHE: name = "CACHE"; break; case TYPE_FIXED: name = "FIXED"; break; case TYPE_SINGLE: name = "SINGLE"; break; default: name = "POOL_THREAD"; break; } } if (deliver == null) { if (ThreadToolUtils.isAndroid) { deliver = AndroidDeliver.getInstance(); } else { deliver = JavaDeliver.getInstance(); } } return new PoolThread(type, size, priority, name, callback, deliver, pool); } } }
4.6.2 添加設置thread配置信息的方法php
/** * 爲當前的任務設置線程名。 * @param name 線程名字 * @return PoolThread */ public PoolThread setName(String name) { getLocalConfigs().name = name; return this; } /** * 設置當前任務的線程回調,若是未設置,則應使用默認回調。 * @param callback 線程回調 * @return PoolThread */ public PoolThread setCallback (ThreadCallback callback) { getLocalConfigs().callback = callback; return this; } /** * 設置當前任務的延遲時間. * 只有當您的線程池建立時,它纔會產生效果。 * @param time 時長 * @param unit time unit * @return PoolThread */ public PoolThread setDelay (long time, TimeUnit unit) { long delay = unit.toMillis(time); getLocalConfigs().delay = Math.max(0, delay); return this; } /** * 設置當前任務的線程傳遞。若是未設置,則應使用默認傳遞。 * @param deliver thread deliver * @return PoolThread */ public PoolThread setDeliver(Executor deliver){ getLocalConfigs().deliver = deliver; return this; }
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5); ExecutorService singleThreadPool = Executors.newSingleThreadExecutor(); ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5); ScheduledExecutorService singleThreadScheduledPool = Executors.newSingleThreadScheduledExecutor();
/** * 建立線程池,目前支持如下四種 * @param type 類型 * @param size 數量size * @param priority 優先級 * @return */ private ExecutorService createPool(int type, int size, int priority) { switch (type) { case Builder.TYPE_CACHE: //它是一個數量無限多的線程池,都是非核心線程,適合執行大量耗時小的任務 return Executors.newCachedThreadPool(new DefaultFactory(priority)); case Builder.TYPE_FIXED: //線程數量固定的線程池,所有爲核心線程,響應較快,不用擔憂線程會被回收。 return Executors.newFixedThreadPool(size, new DefaultFactory(priority)); case Builder.TYPE_SCHEDULED: //有數量固定的核心線程,且有數量無限多的非核心線程,適合用於執行定時任務和固定週期的重複任務 return Executors.newScheduledThreadPool(size, new DefaultFactory(priority)); case Builder.TYPE_SINGLE: default: //內部只有一個核心線程,全部任務進來都要排隊按順序執行 return Executors.newSingleThreadExecutor(new DefaultFactory(priority)); } }
public interface ThreadFactory { /** * Constructs a new {@code Thread}. Implementations may also initialize * priority, name, daemon status, {@code ThreadGroup}, etc. * * @param r a runnable to be executed by new thread instance * @return constructed thread, or {@code null} if the request to * create a thread is rejected */ Thread newThread(Runnable r); }
public class MyThreadFactory implements ThreadFactory { private int priority; public MyThreadFactory(int priority) { this.priority = priority; } @Override public Thread newThread(@NonNull Runnable runnable) { Thread thread = new Thread(runnable); thread.setPriority(priority); return thread; } }
/** * 啓動 * @param delay 延遲執行的時間,注意默認單位是TimeUnit.MILLISECONDS * @param pool pool線程池 * @param task runnable */ void postDelay(long delay, final ExecutorService pool, final Runnable task) { if (delay == 0) { //若是時間是0,那麼普通開啓 pool.execute(task); return; } //延時操做 dispatcher.schedule(new Runnable() { @Override public void run() { //在未來的某個時間執行給定的命令。該命令能夠在新線程、池線程或調用線程中執行 pool.execute(task); } }, delay, TimeUnit.MILLISECONDS); }