Android开发-多线程的创建方式

两种基本创建方式

  1. 继承Thread类,覆写run方法。
  2. 通过实现Runnable接口,或继承自Thread类,覆写run方法。
1.public class MainActivity extends AppCompatActivity  {
       ActivityMainBinding activityMainBinding;
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        activityMainBinding =  DataBindingUtil.setContentView(this,R.layout.activity_main);

        //子线程的创建
       ThreadTaskDemo1 threadTask1 = new ThreadTaskDemo1();  
       threadTask1.setName("task-1");  
       threadTask1.start();  
  
       ThreadTaskDemo1 threadTask2 = new ThreadTaskDemo1();  
       threadTask2.setName("task-2");  
       threadTask2.start();  
    }

 class ThreadTaskDemo1 extends Thread{
        @Override
        public void run() {
            System.out.println("thread name:"+Thread.currentThread().getName());
        }
    }
}

运行输出
在这里插入图片描述
实现Runnable接口创建线程

	Thread task1 = new Thread(new RunnableTaskDemo());  
	task1.setName("task-r1");  
	task1.start();  	  
	Thread task2 = new Thread(new RunnableTaskDemo());  
	task2.setName("task-r2");  
	task2.start();

实现Runnable接口,重写run方法

	class RunnableTaskDemo implements Runnable{  
	        @Override  
	        public void run() {  
	            System.out.println("thread name:"+Thread.currentThread().getName());  
  
        }  
	    }  

运行结果

这两种创建方式最主要的区别如果是实现Runnable接口的方式创建,可以给多个Thread用,这样的话可以很容易实现共享数据。但要注意避免线程安全问题。而使用继承Thread的方式创建线程则无法共享数据,一般推荐使用实现Runnable接口来创建线程,
实现Runnable创建线程的好处有:

  1. 在java中,因为类是单继承的,而类是可以继承多个接口的,避免了继承的局限 。
    2. 容易实现资源的共享,适合多个线程去处理同一个资源。
    3. 增加程序的健壮性

AsyncTask

首先AsyncTask是一个抽象类,它是由Android封装的一个轻量级异步类,它可以在线程池中执行后台任务,然后把执行的进度和结果传递给主线程并在主线程中更新UI。
AsyncTask的内部封装了两个线程池(SerialExecutor和THREAD_POOL_EXECUTOR)和一个Handler(InternalHandler)。
其中SerialExecutor线程池用于任务的排队,让需要执行的多个耗时任务,按顺序排列,THREAD_POOL_EXECUTOR线程池才真正地执行任务,InternalHandler用于从工作线程切换到主线程。

	public class MyAsyncTask extends AsyncTask<Integer, Integer, String> {  
	    /* 后台执行,比较耗时的操作都可以放在这里。注意这里不能直接操作UI。 
	       此方法在后台线程执行,完成任务的主要工作,通常需要较长的时间。 
       在执行过程中可以调用publicProgress(Progress…)来更新任务的进度。*/  
	    @Override  
	    protected String doInBackground(Integer... params) {  
	        return "ok";  
	    }  
	    //最终用户调用Excute时的接口,当任务执行之前开始调用此方法,可以在这里显示进度对话框/进度条显示  
	    @Override  
	    protected void onPreExecute() { 
	    }  
    /*在doBackground方法中,每次调用publishProgress方法都会触发该方法 
	       可以使用进度条增加用户体验度。 此方法在主线程执行,用于显示任务执行的进度 
	     */  
	    @Override  
      protected void onProgressUpdate(Integer... values) {  
  
	    }  
	    /* 相当于Handler 处理UI的方式,在这里面可以使用在doInBackground 得到的结果处理操作UI。 
	     此方法在主线程执行,任务执行的结果作为此方法的参数返回*/  
	    @Override  
	    protected void onPostExecute(String s) {  
	        super.onPostExecute(s);  
	    }  
	    // 用户调用取消时,要做的操作  
	    @Override  
	    protected void onCancelled() {  
        super.onCancelled();  
    }  
	}  

使用

 @Override  
	   protected void onCreate(Bundle savedInstanceState) {  
	       super.onCreate(savedInstanceState);  
	       setContentView(R.layout.activity_main);  
	       MyAsyncTask task = new MyAsyncTask();  
	       task.execute();  
	    //  task.execute(150);//也可以根据业务需求传参  
	   }  

AsyncTask的缺点:默认使用串行的线程池执行任务,也就是说,如果往这个池里创建10个AsyncTask任务,如有一个一直没结束,比如说阻塞,休眠,那么其他的就无法执行了。
在Android 1.6之前的版本,AsyncTask是串行的,在1.6到2.3的版本,改成了并行的。在2.3之后的版本又修改了,可以支持并行和串行,当想要串行执行时,直接执行execute()方法,如果需要并行执行,则要执行executeOnExecutor(Executor exec,Params… params)。

	MyAsyncTask task = new MyAsyncTask();  
	task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

AsyncTask第二种创建方式,直接执行Runnable接口实现类(串行执行)

	AsyncTask.execute(()->{  
	   System.out.println("AsyncTask thread name "+ Thread.currentThread().getName());  
	        }); 

运行输出
在这里插入图片描述

	//并行的执行方式  
	 AsyncTask.THREAD_POOL_EXECUTOR.execute(()->{  
	     System.out.println("AsyncTask thread name "+ Thread.currentThread().getName());  
	 });  

HandlerThread

HandlerThread适用于轮询场景,通过发送消息的形式执行任务,这也是一个串行的执行方式。这个用得比较少,一般是主线程的Handler用得比较多。在子线程给主线程发送消息。比如在子线程请求数据,然后向主线程发送结果。这里就列出代码,具体可百度。

其他

除了上面列出的方式,还有IntentService、ThreadPoolExecutor
IntentService是个服务,它可以在后台运行。一般用于我们需要跨界面获取到后台任务执行进度,比如说我们上传、下载文件,它执行完任务则会结束服务。
ThreadPoolExecutor 线程池重复使用线程,减少创建、销毁线程的开销,一般用于频繁的,消耗资源较少的操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值