一.概述
上一篇多线程使用(一)我们介绍了如何使用实现单个线程来完成任务,今天我们来看看多个线程工作的情况,也就是线程池。
二.原理
概念
Executors 提供四种线程池:
1)newCachedThreadPool 是一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。对于执行很多短期异步任务的程序而言,这些线程池通常可提高程序性能。调用 execute() 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。因此,长时间保持空闲的线程池不会使用任何资源。注意,可以使用 ThreadPoolExecutor 构造方法创建具有类似属性但细节不同(例如超时参数)的线程池。
2)newSingleThreadExecutor 创建是一个单线程池,也就是该线程池只有一个线程在工作,所有的任务是串行执行的,如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它,此线程池保证所有任务的执行顺序按照任务的提交顺序执行。
3)newFixedThreadPool 创建固定大小的线程池,每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小,线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。
4)newScheduledThreadPool 创建一个大小无限的线程池,此线程池支持定时以及周期性执行任务的需求。
当我们使用Executors创建不同类型的线程执行器时,都会返回一个ExecutorService对象,这个对象提供了两个方法来关闭线程池:
- shutdown
不会立即的终止线程池,而是要等所有任务缓存队列中的任务都执行完后才终止,但再也不会接受新的任务 - shutdownNow
立即终止线程池,并尝试打断正在执行的任务,并且清空任务缓存队列,返回尚未执行的任务。
我们用一个例子来看看每个线程执行器的效果,先看效果图
三.代码
public class MainActivity extends AppCompatActivity {
private final int TYPE_MSG_RUN = 1001;
private final int TYPE_MSG_DONE = 1002;
private Thread thread;
private ProgressBar progressBar3;
private ProgressBar progressBar2;
private ProgressBar progressBar1;
private TextView tv_info1;
private TextView tv_info2;
private TextView tv_info3;
private TextView tv_start1;
private TextView tv_start2;
private TextView tv_start3;
private TextView tv_cancel1;
private TextView tv_cancel2;
private TextView tv_cancel3;
private TextView tv_shut_now;
private TextView tv_shut;
private TextView tv_info;
private ExecutorService pool = Executors.newCachedThreadPool();
private Callable<Integer> callable1;
private Future task1;
private Callable<Integer> callable2;
private Future task2;
private Callable<Integer> callable3;
private Future task3;
private final int THREAD1_START = 1001;
private final int THREAD2_START = 1002;
private final int THREAD3_START = 1003;
private int num1 = 0;
private int num2 = 0;
private int num3 = 0;
private android.os.Handler handler = new android.os.Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case THREAD1_START:
tv_info1.setText("线程一: "+msg.arg1);
progressBar1.setProgress(msg.arg1);
break;
case THREAD2_START:
tv_info2.setText("线程二: "+msg.arg1);
progressBar2.setProgress(msg.arg1);
break;
case THREAD3_START:
tv_info3.setText("线程三: "+msg.arg1);
progressBar3.setProgress(msg.arg1);
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
addListener();
}
public void initView(){
tv_info1 = (TextView) findViewById(R.id.tv_info1);
tv_info2 = (TextView) findViewById(R.id.tv_info2);
tv_info3 = (TextView) findViewById(R.id.tv_info3);
progressBar1 = (ProgressBar) findViewById(R.id.progressBar1);
progressBar2 = (ProgressBar) findViewById(R.id.progressBar2);
progressBar3 = (ProgressBar) findViewById(R.id.progressBar3);
tv_start1 = (TextView) findViewById(R.id.tv_start1);
tv_start2 = (TextView) findViewById(R.id.tv_start2);
tv_start3 = (TextView) findViewById(R.id.tv_start3);
tv_cancel1 = (TextView) findViewById(R.id.tv_cancel1);
tv_cancel2 = (TextView) findViewById(R.id.tv_cancel2);
tv_cancel3 = (TextView) findViewById(R.id.tv_cancel3);
tv_shut = (TextView) findViewById(R.id.tv_shut_down);
tv_shut_now = (TextView) findViewById(R.id.tv_shut_down_now);
tv_info = (TextView) findViewById(R.id.tv_info);
}
public void initData(){
progressBar1.setProgress(0);
progressBar1.setMax(100);
progressBar2.setProgress(0);
progressBar2.setMax(100);
progressBar3.setProgress(0);
progressBar3.setMax(100);
}
public void addListener(){
tv_start1.setOnClickListener(onClickListener);
tv_start2.setOnClickListener(onClickListener);
tv_start3.setOnClickListener(onClickListener);
tv_cancel1.setOnClickListener(onClickListener);
tv_cancel2.setOnClickListener(onClickListener);
tv_cancel3.setOnClickListener(onClickListener);
tv_shut .setOnClickListener(onClickListener);
tv_shut_now.setOnClickListener(onClickListener);
}
View.OnClickListener onClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.tv_start1:
if(progressBar1.getProgress() == progressBar1.getMax()){
num1 = 0;
}
startThread1();
break;
case R.id.tv_start2:
if(progressBar2.getProgress() == progressBar2.getMax()){
num2 = 0;
}
startThread2();
break;
case R.id.tv_start3:
if(progressBar3.getProgress() == progressBar3.getMax()){
num3 = 0;
}
startThread3();
break;
case R.id.tv_cancel1:
cancelTask(task1);
break;
case R.id.tv_cancel2:
cancelTask(task2);
break;
case R.id.tv_cancel3:
cancelTask(task3);
break;
case R.id.tv_shut_down:
if(pool!=null&& !pool.isShutdown()){
pool.shutdown();
}
break;
case R.id.tv_shut_down_now:
if(pool!=null&& !pool.isShutdown()){
pool.shutdownNow();
}
break;
}
}
};
public void sendMsg(int num,int what){
Message msg = Message.obtain();
msg.what = what;
msg.arg1 = num;
handler.sendMessage(msg);
}
public void startThread1(){
if(task1!=null&&!task1.isDone()||pool.isShutdown()){
return;
}
callable1 = new Callable<Integer>() {
@Override
public Integer call() throws Exception {
while (num1<100){
num1++;
sendMsg(num1,THREAD1_START);
Thread.sleep(100);
}
return 100;
}
};
task1 = pool.submit(callable1);
}
public void startThread2(){
if(task2!=null&&!task2.isDone()||pool.isShutdown()){
return;
}
callable2 = new Callable<Integer>() {
@Override
public Integer call() throws Exception {
while (num2<100){
num2++;
sendMsg(num2,THREAD2_START);
Thread.sleep(100);
}
return 100;
}
};
task2 = pool.submit(callable2);
}
public void startThread3(){
if(task3!=null&&!task3.isDone()||pool.isShutdown()){
return;
}
callable3 = new Callable<Integer>() {
@Override
public Integer call() throws Exception {
while (num3<100){
num3++;
sendMsg(num3,THREAD3_START);
Thread.sleep(100);
}
return 100;
}
};
//提交一个带有返回结果的任务,返回Future对象
task3 = pool.submit(callable3);
}
public void cancelTask(Future<Integer> task){
if (task != null && !pool.isShutdown()) {
task.cancel(true);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_thread_pool,menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.item_newCachedThreadPool:
pool = Executors.newCachedThreadPool();
tv_info.setText("当前线程池类型: newCachedThreadPool");
break;
case R.id.item_newFixedThreadPool:
pool= Executors.newFixedThreadPool(2);
tv_info.setText("当前线程池类型: newFixedThreadPool");
break;
case R.id.item_newScheduledThreadPool:
pool = Executors.newScheduledThreadPool(1);
tv_info.setText("当前线程池类型: newScheduledThreadPool");
break;
case R.id.item_newSingleThreadExecutor:
pool = Executors.newSingleThreadExecutor();
tv_info.setText("当前线程池类型: newSingleThreadExecutor");
break;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onDestroy() {
super.onDestroy();
if (pool != null && !pool.isShutdown()) {
pool.shutdownNow();
}
}
}
最后给出源码下载地址
点此下载源码