Android基础的多线程实现方式主要有两种,一种是创建一种线程类并直接继承Thread类,重写其run函数实现线程功能,第二种是实现Runnable接口,通过线程辅助类实现线程功能。
继承Thread类
该方式实现的方法比较简单:
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只能单继承),减少了可扩展性;由于一个线程是一个实例对象,不适合资源共享的场景。当线程数量多时多次创建与销毁耗费大量资源。
实现Runnable接口
该方法的实现方式相对复杂一些:
扫描二维码关注公众号,回复:
14969612 查看本文章
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的子类,应采用第一种方法,否则采用第二种方法。