1. 程式人生 > >android基礎--執行緒池

android基礎--執行緒池

        執行緒池、執行緒的高效率使用,靈活控制!這裡用最常用的幾種方式來分別實現應用中使用的執行緒方面的知識,(共寫了兩個不同入口的Activity來分開不同的實現方式,大家可以自行註釋AndroidManifest.xml中的Launch入口或開啟註釋)好了,先隨便列幾個吧,如:AsyncTask 、Runnable 、Thread、ThreadPool、 Executors等等的使用

一:無大小限制的執行緒池執行效果如下

二:限制按順序來執行任務的執行緒池效果如下

三:一個一個任務的執行執行緒池效果如下(與按順序執行效果是一樣的,只是內部實現稍有不同)

四:按指定個數來執行任務的執行緒池效果如下

五:建立一個可在指定時間裡執行任務的執行緒池,亦可重複執行,不常用,效果與四相同

六:按指定工廠模式來執行的執行緒池,效果與四、五一樣,但用方式六建立的執行緒池都有在工廠中指定的執行緒屬性,

比如:執行緒名字、是否為使用者執行緒等等屬性

七:執行緒池中任務執行時可暫停效果圖如下

八:用Runnable、ConcurrentLinkedQueue、ConcurrentMap、Future、ExecutorService關聯實現的效果圖如下

(備註:為了寫文章加註釋還有查詢的時候方便,把所有的主類及輔助類以內部類的形式寫到一個.java檔案裡面了,如果朋友們覺得看著亂,不爽的話,可以自行將裡面的類抽取到單獨的.java檔案中,幾分鐘搞定的事!)

方式一(純ExecutorService、AsyncTask、Runnable關聯實現相關檔案如下):

         1.1:主類檔案(Main.java)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396

397

398

399

400

401

402

403

404

405

406

407

408

409

410

/*

* FileName:  Main.java

* Description:  <description>

* Modify Date:   2013-10-15

* Follow Order No.:  <Follow Order No.>

* Modify Order No.:  <Modify Order No.>

* Modify Content:  <modify content >

*/

package com.xxxx.threadpooltest;

 

import java.util.ArrayList;

import java.util.List;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.ThreadFactory;

 

import android.annotation.TargetApi;

import android.app.Activity;

import android.content.Context;

import android.os.AsyncTask;

import android.os.Build;

import android.os.Bundle;

import android.os.SystemClock;

import android.util.AttributeSet;

import android.util.Log;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.AdapterView;

import android.widget.AdapterView.OnItemClickListener;

import android.widget.BaseAdapter;

import android.widget.LinearLayout;

import android.widget.ListView;

import android.widget.ProgressBar;

import android.widget.TextView;

import android.widget.Toast;

 

/**

* @TODO [The Class File Description]

* @version [version-code, 2013-10-15]

* @since [Product/module]

*/

@TargetApi(Build.VERSION_CODES.HONEYCOMB)

public class Main extends Activity

{

    private static int order = 0;

 

    /** 總共多少任務(根據CPU個數決定建立活動執行緒的個數,這樣取的好處就是可以讓手機承受得住) */

    // private static final int count = Runtime.getRuntime().availableProcessors() * 3 + 2;

 

    /** 總共多少任務(為了效果明顯,所以寫死了為10個,如果在手機上的話,推薦使用上面的那個count) */

    private static final int count = 10;

 

    /** 每次只執行一個任務的執行緒池 */

    private static ExecutorService singleTaskExecutor = null;

 

    /** 每次執行限定個數個任務的執行緒池 */

    private static ExecutorService limitedTaskExecutor = null;

 

    /** 所有任務都一次性開始的執行緒池 */

    private static ExecutorService allTaskExecutor = null;

 

    /** 建立一個可在指定時間裡執行任務的執行緒池,亦可重複執行 */

    private static ExecutorService scheduledTaskExecutor = null;

 

    /** 建立一個可在指定時間裡執行任務的執行緒池,亦可重複執行(不同之處:使用工程模式) */

    private static ExecutorService scheduledTaskFactoryExecutor = null;

 

    private List<AsyncTaskTest> mTaskList = null;

 

    /** 任務是否被取消 */

    private boolean isCancled = false;

 

    /** 是否點選並取消任務標示符 */

    private boolean isClick = false;

 

    /** 執行緒工廠初始化方式一 */

    ThreadFactory tf = Executors.defaultThreadFactory();

 

    /** 執行緒工廠初始化方式二 */

    private static class ThreadFactoryTest implements ThreadFactory

    {

 

        @Override

        public Thread newThread(Runnable r)

        {

            Thread thread = new Thread(r);

            thread.setName("xxxxx_ThreadFactory");

            thread.setDaemon(true); // 將使用者執行緒變成守護執行緒,預設false

            return thread;

        }

    }

 

    static

    {

        singleTaskExecutor = Executors.newSingleThreadExecutor();// 每次只執行一個執行緒任務的執行緒池

        limitedTaskExecutor = Executors.newFixedThreadPool(3);// 限制執行緒池大小為7的執行緒池

        allTaskExecutor = Executors.newCachedThreadPool(); // 一個沒有限制最大執行緒數的執行緒池

        scheduledTaskExecutor = Executors.newScheduledThreadPool(3);// 一個可以按指定時間可週期性的執行的執行緒池

        scheduledTaskFactoryExecutor = Executors.newFixedThreadPool(3, new ThreadFactoryTest());// 按指定工廠模式來執行的執行緒池

        scheduledTaskFactoryExecutor.submit(new Runnable()

        {

            @Override

            public void run()

            {

                Log.i("KKK", "This is the ThreadFactory Test  submit Run! ! ! ");

            }

        });

    };

 

    @Override

    public void onCreate(Bundle icicle)

    {

        super.onCreate(icicle);

        setContentView(R.layout.demo);

        final ListView taskList = (ListView)findViewById(R.id.task_list);

        taskList.setAdapter(new AsyncTaskAdapter(getApplication(), count));

        taskList.setOnItemClickListener(new OnItemClickListener()

        {

 

            @Override

            public void onItemClick(AdapterView<?> parent, View view, int position, long id)

            {

                if (position == 0) // 以第一項為例,來測試關閉執行緒池

                {

                    /**

                     * 會關閉執行緒池方式一:但不接收新的Task,關閉後,正在等待 執行的任務不受任何影響,會正常執行,無返回值!

                     */

                    // allTaskExecutor.shutdown();

 

                    /**

                     * 會關閉執行緒池方式二:也不接收新的Task,並停止正等待執行的Task

                     * (也就是說, 執行到一半的任務將正常執行下去),最終還會給你返回一個正在等待執行但執行緒池關閉

                     * 卻沒有被執行的Task集合!

                     */

                    List<Runnable> unExecRunn = allTaskExecutor.shutdownNow();

 

                    for (Runnable r : unExecRunn)

                    {

                        Log.i("KKK", "未執行的任務資訊:=" + unExecRunn.toString());

                    }

                    Log.i("KKK", "Is shutdown ? = " + String.valueOf(allTaskExecutor.isShutdown()));

                    allTaskExecutor = null;

                }

 

                // 以第二項為例來測試是否取消執行的任務

                AsyncTaskTest sat = mTaskList.get(1);

                if (position == 1)

                {

                    if (!isClick)

                    {

                        sat.cancel(true);

                        isCancled = true;

                        isClick = !isClick;

                    }

                    else

                    {

                        sat.cancel(false);

                        isCancled = false;

                        // isClick = false;

                        isClick = !isClick;

                        if (null != sat && sat.getStatus() == AsyncTask.Status.RUNNING)

                        {

                            if (sat.isCancelled())

                            {

                                sat = new AsyncTaskTest(sat.mTaskItem);

                            }

                            else

                            {

                                Toast.makeText(Main.this, "A task is already running, try later", Toast.LENGTH_SHORT).show();

                            }

                        }

 

                        /**

                         * 由於上面測試關閉,在不重新生成allTaskExecutor的同時,會報異常(沒有可以使用的執行緒池,

                         * 故此處重新生成執行緒池物件)

                         */

                        if (allTaskExecutor == null)

                        {

                            allTaskExecutor = Executors.newCachedThreadPool();

                        }

                        sat.executeOnExecutor(allTaskExecutor); // The task is already running(這也是個異常哦,小心使用! )

                    }

                }

                else

                {

                    sat.cancel(false);

                    isCancled = false;

                    // sat.execute(sat.mTaskItem);

                    // sat.executeOnExecutor(allTaskExecutor);

                }

 

            }

        });

    }

 

    /**

     * @TODO [ListView Item的條目介面卡]

     * @version [version-code, 2013-10-22]

     * @since [Product/module]

     */

    private class AsyncTaskAdapter extends BaseAdapter

    {

        private Context mContext;

 

        private LayoutInflater mFactory;

 

        private int mTaskCount;

 

        public AsyncTaskAdapter(Context context, int taskCount)

        {

            mContext = context;

            mFactory = LayoutInflater.from(mContext);

            mTaskCount = taskCount;

            mTaskList = new ArrayList<AsyncTaskTest>(taskCount);

        }

 

        @Override

        public int getCount()

        {

            return mTaskCount;

        }

 

        @Override

        public Object getItem(int position)

        {

            return mTaskList.get(position);

        }

 

        @Override

        public long getItemId(int position)

        {

            return position;

        }

 

        @Override

        public View getView(int position, View convertView, ViewGroup parent)

        {

            if (convertView == null)

            {

                convertView = mFactory.inflate(R.layout.list_view_item, null);

                AsyncTaskTest task = new AsyncTaskTest((MyListItem)convertView);

 

                /**

                 * 下面兩種任務執行效果都一樣,形變質不變

                 * */

                // task.execute();

                // task.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);

 

                /**

                 * 下面的方式在小於API 11級時效果是一樣的,但在高版本中的稍微有點不同,可以看以下AsyncTask

                 * 核心變數的定義就知道了使用如下

                 * 方式時,系統會預設的採用五個一組,五個一組的方式來執行我們的任務,

                 * 定義在:AsyncTask.class中,private static final int CORE_POOL_SIZE = 5;

                 * */

                // use AsyncTask#THREAD_POOL_EXECUTOR is the same to older version #execute() (less than API 11)

                // but different from newer version of #execute()

                // task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

 

                /**

                 * 一個一個執行我們的任務,效果與按順序執行是一樣的(AsyncTask.SERIAL_EXECUTOR)

                 * */

                // task.executeOnExecutor(singleTaskExecutor);

 

                /**

                 * 按我們指定的個數來執行任務的執行緒池

                 * */

                // task.executeOnExecutor(limitedTaskExecutor);

 

                /**

                 * 不限定指定個數的執行緒池,也就是說:你往裡面放了幾個任務,他全部同一時間開始執行,

                 * 不管你手機受得了受不了

                 * */

                task.executeOnExecutor(allTaskExecutor);

 

                /**

                 * 建立一個可在指定時間裡執行任務的執行緒池,亦可重複執行

                 * */

                // task.executeOnExecutor(scheduledTaskExecutor);

 

                /**

                 * 建立一個按指定工廠模式來執行任務的執行緒池,可能比較正規,但也不常用

                 */

                // task.executeOnExecutor(scheduledTaskFactoryExecutor);

                mTaskList.add(task);

            }

            return convertView;

        }

    }

 

    class AsyncTaskTest extends AsyncTask<Void, Integer, Void>

    {

        private MyListItem mTaskItem;

 

        private String id;

 

        private AsyncTaskTest(MyListItem item)

        {

            mTaskItem = item;

            if (order < count || order == count)

            {

                id = "執行:" + String.valueOf(++order);

            }

            else

            {

                order = 0;

                id = "執行:" + String.valueOf(++order);

            }

        }

 

        @Override

        protected void onPreExecute()

        {

            mTaskItem.setTitle(id);

        }

 

        /**

         * Overriding methods

         */

        @Override

        protected void onCancelled()

        {

            super.onCancelled();

        }

 

        @Override

        protected Void doInBackground(Void... params)

        {

            if (!isCancelled() && isCancled == false) // 這個地方很關鍵,如果不設定標誌位的話,直接setCancel(true)是無效的

            {

                int prog = 0;

 

                /**

                 * 下面的while中,寫了個分支用來做個假象(任務東西剛開始下載的時候,速度快,

                 * 快下載完成的時候就突然間慢了下來的效果, 大家可以想象一下,類似:PP手機助手、91手機助手中

                 * 或其它手機應用中,幾乎都有這個假象,開始快,結束時就下載變慢了,講白了 就是開發的人不想讓你

                 * 在下載到大於一半的時候,也就是快下載完的時候去點取消,你那樣得多浪費!所以造個假象,

                 * 讓你不想去取消而已)

                 */

                while (prog < 101)

                {

                    if ((prog > 0 || prog == 0) && prog < 70) // 小於70%時,加快進度條更新

                    {

                        SystemClock.sleep(100);

                    }

                    else

                    // 大於70%時,減慢進度條更新

                    {

                        SystemClock.sleep(300);

                    }

 

                    publishProgress(prog); // 更新進度條

                    prog++;

                }

            }

            return null;

        }

 

        @Override

        protected void onPostExecute(Void result)

        {

        }

 

        @Override

        protected void onProgressUpdate(Integer... values)

        {

            mTaskItem.setProgress(values[0]); // 設定進度

        }

    }

}

 

/**

* @TODO [一個簡單的自定義 ListView Item]

* @version [version-code, 2013-10-22]

* @since [Product/module]

*/

class MyListItem extends LinearLayout

{

    private TextView mTitle;

 

    private ProgressBar mProgress;

 

    public MyListItem(Context context, AttributeSet attrs)

    {

        super(context, attrs);

    }

 

    public MyListItem(Context context)

    {

        super(context);

    }

 

    public void setTitle(String title)

    {

        if (mTitle == null)

        {

            mTitle = (TextView)findViewById(R.id.task_name);

        }

        mTitle.setText(title);

    }

 

    public void setProgress(int prog)

    {

        if (mProgress == null)

        {

            mProgress = (ProgressBar)findViewById(R.id.task_progress);

        }

        mProgress.setProgress(prog);

    }

}

 

1.2:佈局檔案

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:paddingLeft="10dip"

    android:paddingRight="10dip"

    android:orientation="vertical" >

    <ListView android:id="@+id/task_list"

        android:layout_width="fill_parent"

        android:layout_height="wrap_content"

        android:divider="#cccccc"

        android:dividerHeight="0.6dip"

        android:footerDividersEnabled="true"

        android:headerDividersEnabled="true" />

</LinearLayout>

方式二(Runnable、ConcurrentLinkedQueue、ConcurrentMap、Future、ExecutorService關聯實現的相關檔案如 下):

          2.1:主類檔案(MyRunnableActivity.java)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

/*

* FileName:  MyRunnableActivity.java

* CopyRight:  Belong to  <xxxxx Technologies > own

* Description:  <description>

* Modify Date:   2013-10-21

* Follow Order No.:  <Follow Order No.>

* Modify Order No.:  <Modify Order No.>

* Modify Content:  <modify content >

*/

package com.xxxxx.threadpooltest;

 

import java.util.Iterator;

import java.util.Map;

import java.util.concurrent.ConcurrentHashMap;

import java.util.concurrent.ConcurrentLinkedQueue;

import java.util.concurrent.ConcurrentMap;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.Future;

 

import android.app.Activity;

import android.os.Bundle;

import android.os.Handler;

import android.os.Message;

import android.util.Log;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.ProgressBar;

import android.widget.Toast;

 

/**

* @TODO [執行緒池控制 ]

* @version [version-code, 2013-10-22]

* @since [Product/module]

*/

public class MyRunnableActivity extends Activity implements OnClickListener

{

 

    /** 任務執行佇列 */

    private ConcurrentLinkedQueue<MyRunnable> taskQueue = null;

 

    /**

     * 正在等待執行或已經完成的任務佇列

     *

     * 備註:Future類,一個用於儲存非同步任務執行的結果,比如:判斷是否取消、是否可以取消、

     * 是否正在執行、是否已經完成等

     *

     * */

    private ConcurrentMap<Future, MyRunnable> taskMap = null;

 

    /**

     * 建立一個不限制大小的執行緒池 此類主要有以下好處

     * 1,以共享的無界佇列方式來執行這些執行緒.

     * 2,執行效率高。

     * 3,在任意點,在大多數 nThreads 執行緒會處於處理任務的活動狀態

     * 4,如果在關閉前的執行期間由於失敗而導致任何執行緒終止,那麼一個新執行緒將代替它執行後續的任務(如果需要)。

     *

     * */

    private ExecutorService mES = null;

 

    /** 在此類中使用同步鎖時使用如下lock物件即可,官方推薦的,

     * 不推薦直接使用MyRunnableActivity.this型別的,可以詳細讀一下/framework/app下面的隨便一個專案

     */

    private Object lock = new Object();

 

    /** 喚醒標誌,是否喚醒執行緒池工作 */

    private boolean isNotify = true;

 

    /** 執行緒池是否處於執行狀態(即:是否被釋放!) */

    private boolean isRuning = true;

 

    /** 任務進度 */

    private ProgressBar pb = null;

 

    /** 用此Handler來更新我們的UI */

    private Handler mHandler = null;

 

    /**

     * Overriding methods

     *

     * @param savedInstanceState

     */

    @Override

    protected void onCreate(Bundle savedInstanceState)

    {

        // TODO Auto-generated method stub

        super.onCreate(savedInstanceState);

        setContentView(R.layout.my_runnable_main);

        init();

    }

 

    public void init()

    {

        pb = (ProgressBar)findViewById(R.id.progressBar1);

        findViewById(R.id.button1).setOnClickListener(this);

        findViewById(R.id.button2).setOnClickListener(this);

        findViewById(R.id.button3).setOnClickListener(this);

        findViewById(R.id.button4).setOnClickListener(this);

        findViewById(R.id.button5).setOnClickListener(this);

        taskQueue = new ConcurrentLinkedQueue<MyRunnable>();

        taskMap = new ConcurrentHashMap<Future, MyRunnable>();

        if (mES == null)

        {

            mES = Executors.newCachedThreadPool();

        }

 

        // 用於更新ProgressBar進度條

        mHandler = new Handler()

        {

            /**

             * Overriding methods

             *

             * @param msg

             */

            @Override

            public void handleMessage(Message msg)

            {

                super.handleMessage(msg);

                pb.setProgress(msg.what);

            }

 

        };

 

    }

 

    /**

     * Overriding methods

     *

     * @param v

     */

    @Override

    public void onClick(View v)

    {

        switch (v.getId())

        {

            case R.id.button1:

                start();

                break;

            case R.id.button2:

                stop();

                break;

            case R.id.button3:

                reload(new MyRunnable(mHandler));

                break;

            case R.id.button4:

                release();

                break;

            case R.id.button5:

                addTask(new MyRunnable(mHandler));

                break;

 

            default:

                break;

        }

    }

 

    /**

     * <Summary Description>

     */

    private void addTask(final MyRunnable mr)

    {

        mHandler.sendEmptyMessage(0);

 

        if (mES == null)

        {

            mES = Executors.newCachedThreadPool();

            notifyWork();

        }

 

        if (taskQueue == null)

        {

            taskQueue = new ConcurrentLinkedQueue<MyRunnable>();

        }

 

        if (taskMap == null)

        {

            taskMap = new ConcurrentHashMap<Future, MyRunnable>();

        }

 

        mES.execute(new Runnable()

        {

 

            @Override

            public void run()

            {

                /**

                 * 插入一個Runnable到任務佇列中 這個地方解釋一下,offer跟add方法,試了下,效果都一樣,沒區別,

                 * 官方的解釋如下:

                 * 1 offer : Inserts the specified element at the tail of this queue. As the queue is unbounded,

                 * this method will never return {@code false}.

                 * 2 add: Inserts the specified element at the tail of this queue. As the queue is

                 * unbounded, this method will never throw {@link IllegalStateException} or return {@code false}.

                 * */

                taskQueue.offer(mr);

                // taskQueue.add(mr);

                notifyWork();

            }

        });

 

        Toast.makeText(MyRunnableActivity.this, "已新增一個新任務到執行緒池中 !", 0).show();

    }

 

    /**

     * <Summary Description>

     */

    private void release()

    {

        Toast.makeText(MyRunnableActivity.this, "釋放所有佔用的資源!", 0).show();

 

        /** 將ProgressBar進度置為0 */

        mHandler.sendEmptyMessage(0);

        isRuning = false;

 

        Iterator iter = taskMap.entrySet().iterator();

        while (iter.hasNext())

        {

            Map.Entry<Future, MyRunnable> entry = (Map.Entry<Future, MyRunnable>)iter.next();

            Future result = entry.getKey();

            if (result == null)

            {

                continue;

            }

            result.cancel(true);

            taskMap.remove(result);

        }

        if (null != mES)

        {

            mES.shutdown