Android基础的多线程实现方式主要有两种,一种是创建一种线程类并直接继承Thread类,重写其run函数实现线程功能,第二种是实现Runnable接口,通过线程辅助类实现线程功能。
该方式实现的方法比较简单:
1.自定义一个类,令该类继承Thread类。
2.在该类中重写run方法,在其中实现线程的功能。
3.实例化该类,调用start方法启动线程
假设使用两个线程进行计数操作,可以通过该方法实现:
- package com.example.threadtest;
-
- import androidx.appcompat.app.AppCompatActivity;
-
- import android.os.Bundle;
- import android.util.Log;
- import android.view.View;
- import android.widget.Button;
-
- public class MainActivity extends AppCompatActivity {
- Button button;
- //自定义一个内部类
- private class MyThread extends Thread{
- private int number = 0;
- private String mName;
- private int mTime;
- //构造函数
- public MyThread(String name,int time){
- mName = name;
- mTime = time;
- }
- //重写run方法,实现计数功能
- @Override
- public void run(){
- while(number<99){
- number++;
- System.out.println(mName + " " +number);
- //延时计数
- try {
- Thread.sleep(mTime);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- //按下按钮之后启动线程
- button = (Button) findViewById(R.id.button);
- button.setOnClickListener(new View.OnClickListener(){
- @Override
- public void onClick(View v){
- //实例化两个线程对象
- MyThread t1 = new MyThread("thread1",1000);
- MyThread t2 = new MyThread("thread2",2000);
- //启动线程,线程run函数执行完自动结束线程
- t1.start();
- t2.start();
- }
- });
- }
- }
除了显式定义一个类,也可以使用匿名类直接创建一个Thread对象并在其中重写run函数。
匿名类相比显式定义类,使用更方便简洁,但是失去了复用性,适合于一次性启用的线程。
使用自定义类继承Thread类的方法的优点是实现比较简单。
缺点是占用了自定义类的继承名额(java只能单继承),减少了可扩展性;由于一个线程是一个实例对象,不适合资源共享的场景。当线程数量多时多次创建与销毁耗费大量资源。
该方法的实现方式相对复杂一些:
1.自定义一个类,该类实现Runnable接口,该类是线程辅助类,并不是真正的线程类。
2.重写类里的run函数,实现线程功能。
3.实例化该类。
4.将该类对象作为参数,实例化Thread类。
5.启动线程
这次我们实现共享变量,令两个线程对同一个变量进行计数:
- package com.example.threadtest2;
-
- import androidx.appcompat.app.AppCompatActivity;
-
- import android.os.Bundle;
- import android.view.View;
- import android.widget.Button;
-
- public class MainActivity extends AppCompatActivity {
-
- Button button;
- //创建线程类,实现Runnable接口
- private class MyThread implements Runnable{
- //变量资源是共享的
- private int number = 0;
- //重写run方法,实现线程功能
- @Override
- public void run(){
- while (number<99){
- number++;
- System.out.println(Thread.currentThread().getName()+" "+number);
- //延时计数
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- //按下按钮启动线程
- button = (Button) findViewById(R.id.button);
- button.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- //由于是共用资源,因此只需要实例化一个线程辅助类
- MyThread mt = new MyThread();
- //实例化两个线程
- Thread t1 = new Thread(mt,"Thread1");
- Thread t2 = new Thread(mt,"Thread2");
- //启动线程
- t1.start();
- t2.start();
- }
- });
- }
- }
线程辅助类通用可以使用匿名类的方式进行实例化。
匿名类相比显式定义类,使用更方便简洁,但是失去了复用性,适合于一次性启用的线程。
该方案的优点是实现了线程间资源的共享;并且不占用继承名额。
缺点是写法稍微复杂了一些。
综上,如果需要修改或者增强Thread的子类,应采用第一种方法,否则采用第二种方法。