ダイナミック制御スレッド池で実行中のジョブ

3618 ワード

簡単に見えるし、簡単ですが、余分なコードを実行しないと困ります。
まず簡単に実現しましょう。任務を追加する時にList記録を利用して実行した任務を記録できます。
注意このRunnableは、カスタマイズされ、中に停止タスクを追加する方法でなければならないので、通常は、実行ステップ中か、または前に実行を継続するかどうかを判断しても良いです。例えば、
public class MyRunnballe implements Runnable{
public volatile book exit=false;
 
	Override
	void run(){
	   if(exit)
	      return;
	   ......//    	
	}
 
)
タスクを終了する必要がある場合は、停止したいタスクを直接にタスクのexit=trueに取得します。
これで退出できます。
普通は
  DiscardOldestPolicy   
public void rejectedExecution(Runnable r, ThreadPoolExecutor e)  ;
              for      ;
                      ThreadPoolExecutor    ,           ;
              ,                  ,                ;           ;
                      
 
public volatile List mRunningTasks=new LinkedList<>();// TODO: 2017/5/14         
 
final void runWorker(Worker w) { Thread wt = Thread.currentThread(); Runnable task = w.firstTask; w.firstTask = null; w.unlock(); // allow interrupts  boolean completedAbruptly = true; try { while (task != null || (task = getTask()) != null) {  w.lock(); // If pool is stopping, ensure thread is interrupted;  // if not, ensure thread is not interrupted. This  // requires a recheck in second case to deal with  // shutdownNow race while clearing interrupt  if ((runStateAtLeast(ctl.get(), STOP) || (Thread.interrupted() && runStateAtLeast(ctl.get(), STOP))) && !wt.isInterrupted()) wt.interrupt(); try { beforeExecute(wt, task);  Throwable thrown = null; try { mRunningTasks.add(task);// worker                    ; //System.out.println("     ");  task.run(); } catch (RuntimeException x) { thrown = x; throw x; } catch (Error x) { thrown = x; throw x; } catch (Throwable x) { thrown = x; throw new Error(x); } finally { afterExecute(task, thrown); } } finally {  mRunningTasks.remove(task);//             task = null; w.completedTasks++;   w.unlock(); } } completedAbruptly = false;   } finally {   processWorkerExit(w, completedAbruptly);  } }
これらのタスクを終了する方法を追加します。
 
public void tryStopRunningTasks(){ ControllableRunnable controllableRunnable; Runnable runnable; try { for (int i=0;i< mRunningTasks.size();i++ ){ if (i>=mRunningTasks.size()-1) break; runnable=mRunningTasks.get(i); controllableRunnable=(ControllableRunnable)runnable; if (controllableRunnable==null||controllableRunnable.exit==true) continue; controllableRunnable.exit=true; } } catch (NullPointerException e1) { } }
最後に書き直します
public void rejectedExecution(Runnable r, ThreadPoolExecutor e)  
 
public void rejectedExecution(Runnable r, ControllableThreadPoolExecutor e) { if (!e.isShutdown()) { e.getQueue().poll();// TODO: 2017/5/10               e.tryStopRunningTasks();  e.executeControllableRunnable((ControllableRunnable) r);  } }
このようにスレッド池のタスクキャッシュの列がいっぱいになったら(スレッド池のすべてのスレッドがブロックされていることを意味しています。このとき、実行中のタスクが終了しないと、すべてのタスクがブロックされてしまいます。)、スレッドがスムーズに流れ、ブロックが発生するのを防ぐことができます。
ThreadPoolExecutor.java   
RejectedExecutionHandler.java  
ソースは以下の2つの注意を払う必要があります。
            
ダウンロード ソースのダウンロード