当前位置:天才代写 > tutorial > 安卓教程 > Android学习笔记:多个AsyncTask实例的并发问题

Android学习笔记:多个AsyncTask实例的并发问题

2021-02-25 12:58 星期四 所属: 安卓教程 浏览:471

AsyncTask是Android给开发人员出示的一个简易轻量的线程同步类,根据它我们可以非常容易新创建一个进程让在后台管理做一些用时的实际操作(如IO实际操作、互联网浏览等),并在这个全过程中升级UI。往往说它轻量,是由于不用立即应用Handler、Thread等专业知识,应用起來非常简单,但也失去一些协调能力,针对一些繁杂的情景解决起來不方便。

假如一个APP过程中另外只建立和运作一个AsyncTask案例,则不容易有一切难题。但假如在一个过程中如果有好几个AsyncTask任务另外在实行,难题就非常复杂了。下边大家根据事例看来(大家事例是在Android 4中运作的)。

一、测试1(默认设置好几个Task是串行通信实行的)

1、建立一个默认设置的app工程项目

2、建立一个类承继AsyncTask,编码以下

package com.example.asynctaskdemo;

import android.os.AsyncTask;

public class MyAsyncTask extends AsyncTask<String, Void, String>{
	private String name;
	public MyAsyncTask(String name){
		this.name = name;
	}

	@Override
	protected String doInBackground(String... params) {
		System.out.println(name " is run " System.currentTimeMillis() " thread id " Thread.currentThread().getId());
		try {
			Thread.sleep(1000*10);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return null;
	}

}

3、在Activity的onCreate方式中应用该Task,编码以下

@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		for(int i=1;i<5;i  ){
			MyAsyncTask task = new MyAsyncTask("task" i);
			task.execute(new String[0]);
		}
	}

  我们在调节对话框,观查MyAsyncTask打印信息的间距和次序。发觉这建立的4个每日任务是串行通信实行的,并并不是高并发的。

科学研究了AsyncTask的完成关键点,在建立一个AsyncTask并根据其execute方式运行实行时,AsyncTask并并不是建立一个单独的进程去实行。AsyncTask是根据线程池来管理方法和生产调度过程中的全部Task的。

在 Android2.3之前的版本号(SDK/API 高于或等于10的版本号)

好几个AsyncTask任务是高并发实行的,换句话说假如运行好几个task,则会高并发实行。但高并发实行的总数在于AsyncTask內部的线程池限定总数。假如超出了这一额度,新的每日任务只有等候。

 在Android 3.0及之后版本号(SDK/API 高于或等于11的版本号)

Google从Android 3.0逐渐对AsyncTask的生产调度实行作出了一些转变 ,针对execute递交的每日任务,按顺序每一次只运作一个。换句话说它是按递交的顺序,每一次只运行一个进程实行一个每日任务,进行以后再实行第二个每日任务,也就是等同于只有一个后台管理进程在实行所递交的每日任务。上边的事例就认证了这一点。

二、让AsyncTask高并发实行

由于默认设置状况下好几个task是串行通信的,那如何让高并发实行呢?AsyncTask提升了一个新的插口executeOnExecutor,这一插口容许开发人员出示自定的线程池来运作和生产调度Thread。大家把上边编码改下:

@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		for(int i=1;i<11;i  ){
			MyAsyncTask task = new MyAsyncTask("task" i);
			//task.execute(new String[0]);
			task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, new String[0]);
		}
	}

  这儿大家应用了executeOnExecutor方法替代了execute方式。而且executeOnExecutor方法的第一个主要参数是一个预订义的线程池。这时候这好多个task就可以高并发实行了。这时候大家观查复印的結果,发觉有五个每日任务高并发实行,能够看得出有五个不一样的进程号,查询AsyncTask的源代码,发觉高并发线程数跟机器设备的cpu总数是相关的,因而不一样的机器设备上很有可能见到的結果不完全一致,这一点必须留意。仅有前边的五个每日任务实行完后,才会实行后边的,而且根据复印的进程号能够看得出,后边实行的每日任务是器重原先的进程,并沒有建立新的进程,这就是线程池的功效。

大家再说改下编码,应用Android出示的此外一个预订义的线程池。编码以下:

@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		for(int i=1;i<11;i  ){
			MyAsyncTask task = new MyAsyncTask("task" i);
			//task.execute(new String[0]);
			task.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, new String[0]);
		}
	}

观查打印信息我们可以发觉,这和启用execute方式一样,每一个每日任务全是串行通信实行的。而且这一全过程中数最多建立了五个新的进程。

三、自定线程池

我们可以运用java.util.concurrent.Executors中的各种各样静态方法建立供AsyncTask实行的线程池 ,能够特定进程的总数和生产调度的方法。其方式许多,大家这儿详细介绍在其中二种比较常见的。

1、让每一个AsyncTask任务都独立起一个进程实行,换句话说全部的全是高并发的。编码如:

@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
		for(int i=1;i<11;i  ){
			MyAsyncTask task = new MyAsyncTask("task" i);
			task.executeOnExecutor(newCachedThreadPool, new String[0]);
		}
	}

  仔细观察复印能够看得出,这好几个每日任务全是高并发实行的。

2、建立特定进程总数的线程池,并发数限制便是特定的线程数。但新每日任务造成,沒有空余的进程,就只有等候。编码如:

@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(3);
		for(int i=1;i<11;i  ){
			MyAsyncTask task = new MyAsyncTask("task" i);
			task.executeOnExecutor(newFixedThreadPool, new String[0]);
		}
	}

  仔细观察能够看得出,有3个进程在高并发实行。

小结下,从上边的事例中能够看得出,假如一个过程中存有好几个TASK必须高并发实行的状况,那么就必须采用AsyncTask一些更加深入的专业知识,必须考虑到的难题大量。

 

    关键字:

天才代写-代写联系方式