线程与进程、Android多线程编程

目录

  • 一、概念
    • 1.程序
    • 2.进程
    • 3.并发
    • 4.并行
    • 5.线程
  • 二、Android中的进程与线程
    • 1.安卓的进程
    • 2.安卓的线程
  • 三、Android多线程编程
    • 1.线程的创建
      • 1)继承Thread类
      • 2)实现Runnable接口(常用)
    • 2. 异步消息处理机制
      • 1)Message
      • 2)Handler
      • 3)实战

一、概念

1.程序

程序是为了实现特定任务的一系列指令的有序集合,是存放在磁盘的可执行文件。它本身没有任何运行的含义,它只是一个静态的实体。

2.进程

进程是程序的一次执行过程,是一个动态的概念。

3.并发

并发是多个事件在同一时间间隔内发生
并发是指一个处理器同时处理多个任务,在同一时刻只能有一条指令执行,但多个进程指令被快速的轮换执行,使得在宏观上具有多个进程同时执行的效果,但在微观上并不是同时执行的,只是把时间分成若干段,使多个进程快速交替的执行。

4.并行

并行是多个事件在同一时刻同时进行
并行是指多个处理器或者是多核的处理器同时处理多个不同的任务。作个比喻:并发是一个人同时吃三个馒头,而并行是三个人同时吃三个馒头。

5.线程

线程是进程的一部分,描述指令流执行状态,它是进程中的指令执行流的最小单位。线程是进程中的一个实体,一个进程包括1 ~ n个线程。若把进程称为任务的话,那么线程则是任务中的一个子任务的执行。一个进程中可以有多个线程,他们可以并发的执行多个任务。

为啥会有线程这种东西?因为有并发进行并且共享数据的这种需求;虽然进程也可以满足这种需求,但是它的开销很大(创建进程,进程结束,进程切换… …)。而线程能减少并发执行的时间和空间开销。

总结:
程序是静态的,进程是动态的
程序 = 文件(静态的可执行文件)
进程 = 执行中的程序 = 程序 + 执行状态
并发是一个人做多件事,来回切换。
并行是多个人做多件事,互不干涉。
并发是轮流处理多个任务,并行是同时处理多个任务。
一个进程中可以同时存在多个线程,各个线程之间可以并发执行。

二、Android中的进程与线程

1.安卓的进程

Android中有五种进程:前台进程,可见进程,服务进程,后台进程,空进程。
详细介绍:https://blog.csdn.net/wolfking0608/article/details/83146268

2.安卓的线程

前面我们讲到,一个进程可以包含多个线程,因此进程和线程是包含与被包含的关系。简单情况下,一个进程可以只有一个线程, 即主线程。当一个应用程序启动之后,android系统会为这个应用程序创建一个主线程(Main Thread),它负责渲染视图,分发事件到响应监听器并执行,对界面进行轮询的监听,所以在Android里面主线程也叫UI线程,在UI线程里才能操作界面

三、Android多线程编程

如果我们在UI线程中做一些比较耗时的操作,比如访问网络或者数据库,都可能阻塞UI线程。对于用户来说,APP看起来像是卡住了,更坏的情况是,如果UI线程阻塞时间太长(超过5秒),Android系统会弹出ANR(application not responding)错误提示框。所以为了确保用户体验,主线程必须确保其响应速度,任何时候我们都不应该在主线程中处理非常耗时的任务,而子线程的作用就是完成耗时的操作,确保主线程的响应速度。

下面就让我们从线程的基本用法开始学起吧。

1.线程的创建

1)继承Thread类

 class MyThread extends Thread{@Overridepublic void run(){//线程行为}}//MyThread mt=new MyThread();//mt.start();new MyThread().start(); // 启动子线程,写在主线程中

步骤:
1、定义一个类继承Thread类,并重写Thread类的run()方法,run()方法的方法体就是线程要完成的任务;

2、创建该类的实例对象,即创建了线程对象;

3、调用线程对象的start()方法来启动线程,这样run()方法中的代码就会在子线程当中运行了。
注意,不是调用run()方法启动线程,run方法中只是定义需要执行的任务,如果调用run方法,即相当于在主线程中执行run方法,跟普通的方法调用没有任何区别,此时并不会创建一个新的线程来执行定义的任务。

下面我们通过一个java例子更好地了解一下这种创建线程的方法吧

public class ThreadDemo1 {public static void main(String args[]) { //执行main方法的线程就是主线程Thread t = new MyThread (); // 实例化出一个线程对象t.start();}
}// 继承Thread类
class MyThread extends Thread {public void run() {System.out.println("创建了一个新的线程");}
}

2)实现Runnable接口(常用)

上一个方法虽然代码简单,但有很大的缺点,继承Thread类后就不能再继承别的类了,所以在开发中,优先选择实现Runable接口的方式。实现的方式没有类的单继承性的局限性,且更适合用来处理多个线程有共享数据的情况。

class MyThread implements Runnable {@Overridepublic void run() {//处理具体的逻辑}
}
MyThread myThread = new MyThread();
new Thread(myThread).start();

步骤:
1、定义一个类实现Runnable接口;

2、创建该类的实例对象obj;

3、将obj作为构造函数参数传入Thread类实例对象,这个对象才是真正的线程对象;

4、调用线程对象的start()方法启动该线程。

同样来看个简单的java例子吧

public class ThreadDemo2 {public static void main(String args[]) {MyThread mt = new MyThread();// mt.start(); //会报错,任务类MyThread中没有start()方法// mt.run(); // 仅仅在主线程调用任务类MyThread中的run()方法,并没有新开一个线程Thread t = new Thread(mt); // 传入任务类MyThread对象,实例化出一个线程对象t.start(); // 调用线程对象的start()方法}
}//创建任务类,实现Runnable接口
class MyThread implements Runnable {public void run() {System.out.println("创建了一个新的线程");}
}

如果不想专门再定义一个类去实现Runnable接口,也可以使用匿名类的方式,这种写法更为常见

new Thread(new Runnable() {@Overridepublic void run() {// 处理具体的逻辑}
}).start();

2. 异步消息处理机制

现在我们都知道,耗时操作可以另外创建一个线程来运行以避免堵塞主线程。还有Android不允许在子线程中进行UI操作,因为Android的UI是线程不安全的(具体的原因和实践我在这里就不解释和进行了,想了解的可以上网查或看《第一行代码》)。但是有些时候,我们必须在子线程里去执行一些耗时任务,然后根据任务的执行结果来更新相应的UI控件,这该如何是好呢?
对于这种情况,Android提供了一套异步消息处理机制,完美地解决了这个问题,可以从子线程回到主线程中执行并带回结果。

Android中的异步消息处理主要由4个部分组成:Message、Handler、MessageQueue和Looper。 这里我主要介绍Message和Handler,其余的大家可以参考《第一行代码》进行学习。

1)Message

Message是在线程之间传递的消息,它可以在内部携带少量的信息,用于在不同线程之间交换数据。

2)Handler

Handler顾名思义也就是处理者的意思,它主要是用于发送和处理消息的。发送消息一般是使用Handler的sendMessage()方法,而发出的消息经过一系列地辗转处理后,最终会传递到Handler的handleMessage()方法中。Handler是主线程与子线程的通信媒介。

3)实战

现在我们通过一个具体的例子来实践一下如何使用Message和Handler。新建一个ThreadTest项目,然后修改activity_main.xml中的代码,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><Buttonandroid:id="@+id/change_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Change text" /><TextViewandroid:id="@+id/text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Hello World!"android:textSize="30sp"/></LinearLayout>

布局文件中定义了两个控件,Button用于改变TextView中显示的内容,我们希望在点击Button后可以把TextView中显示的字符串改成Nice to meet you。

接着我们来修改MainActivity中的代码,如下所示:

public class MainActivity extends AppCompatActivity implements View.OnClickListener{private TextView text;private static final int UPDATE_TEXT = 1; // 定义了一个整型常量 UPDATE_TEXT,用于表示更新TextView这个动作@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);text = findViewById(R.id.text);Button changeText = findViewById(R.id.change_text);changeText.setOnClickListener(this);}@Overridepublic void onClick(View view) {switch (view.getId()) {case R.id.change_text:// 开启了一个子线程new Thread(new Runnable() {@Overridepublic void run() {/* 创建了一个Message(android.os.Message)对象,并将它的what字段的值指定为UPDATE_TEXT,然后调用Handler的sendMessage()方法将这条Message发送出去*/Message message = new Message();message.what = UPDATE_TEXT;handler.sendMessage(message);}}).start();break;default:break;}}// 新增一个Handler对象,并重写父类的handleMessage()方法,在这里对具体的Message进行处理。// 使用new handler()来实例化可能会出现警告,在参数中传入Looper.getMainLooper()可以确保Handler是在主线程中private Handler handler = new Handler(Looper.getMainLooper()) {public void handleMessage(Message message) {/* Handler收到Message,并在handleMessage()方法中对它进行处理。注意此时handleMessage()方法中的代码就是在主线程当中运行的了,所以我们可以在这里进行UI操作*/switch (message.what) {case UPDATE_TEXT:// 如果发现Message的what字段的值等于UPDATE_TEXT,就将TextView显示的内容改成Nice to meet youtext.setText("Nice to meet you");break;default:break;}}};}

使用步骤:
1、在主线程中创建一个Handler对象,重写它的handleMessage方法
2、在子线程中创建Message对象
3、调用Handler对象的sendMessage()方法发送Message

这里仅仅是为了举个例子而已,并没有涉及耗时操作,在实际开发过程中,在子线程中会进行一些耗时操作,如网络连接,下载文件,数据库操作等,然后根据这些耗时操作得到的结果来更新UI。


好啦,要讲的内容就那么多了,上面这些内容其实是Android 四大组件中服务的基础。Android/Java提供了很多类/接口来帮助大家完成异步操作,runOnUiThread()方法,AsyncTask抽象类也都常见于Android多线程编程,这些就留着让你们自己去探索啦!

参考资料:
Android进程与线程基本知识
Activity runOnUiThread() 方法使用
Android中AsyncTask的简单用法

线程与进程、Android多线程编程相关推荐

  1. Android多线程编程(一)- 线程基础

    Android多线程编程(一) 到了学习下一部分了,多线程编程一直都是Android经常使用的部份,在进行网络请求或者访问数据库时,为了避免主线程被耗时操作阻塞了进度,通常都会开启子线程进行处理,多线 ...

  2. android: 多线程编程基础

    9.1   服务是什么 服务(Service)是 Android 中实现程序后台运行的解决方案,它非常适合用于去执行那 些不需要和用户交互而且还要求长期运行的任务.服务的运行不依赖于任何用户界面,即使 ...

  3. android 多线程编程

    主线程的职责是创建.显示和更新UI控件.处理UI事件.启动子线程.停止子线程;子线程的职责是进行处理和向主线程发出更新UI消息,而不是直接更新UI. android 多线程编程报错: 05-14 15 ...

  4. Android开发实例——倒计时器——Android多线程编程

    文章目录 一.倒计时器功能描述 二.实现步骤 1.新建Activity,命名为ThreadDemo 2.设计ThreadDemo 的布局文件 3.编写ThreadDemo.java 文件代码 3.1 ...

  5. Android多线程编程

    Android多线程编程 其实就是将耗时操作放在子线程里运行,防止主线程被阻塞,影响软件使用. 线程的基本用法 定义一个线程只需要新建一个类继承自Thread,然后重写父类的run()方法,并在里面编 ...

  6. linux查询某域线程是否满了,Linux多线程编程的时候怎么查看一个进程中的某个线程是否存活...

    pthread_kill: 别被名字吓到,pthread_kill可不是kill,而是向线程发送signal.还记得signal吗,大部分signal的默认动作是终止进程的运行,所以,我们才要用sig ...

  7. 进程、线程及python的多线程编程

    目录 一.进程.线程和并行执行 1.什么是进程.线程 注意 2.什么是并行执行 二.python的多线程编程 threading模块 语法 多线程编程的传参 演示 三.总结 一.进程.线程和并行执行 ...

  8. 线程、进程、多线程、多进程和多任务有啥关系?

    点击上方"朱小厮的博客",选择"设为星标" 后台回复"书",获取后台回复"k8s",可领取k8s资料 可能学习操作系统开 ...

  9. 线程、进程、多线程、多进程 和 多任务 小结

    目录 1 进程 2 线程 3 多进程 4 多线程 5 线程与进程的关系 6 线程和进程的区别 7 进程的优缺点 7.1 进程的优点 7.2 进程的缺点 8 线程的优缺点 8.1 线程的优点 8.2 线 ...

最新文章

  1. (转载)人人都会OSGI--实例讲解OSGI开发
  2. Tomcat Filter 自己动手实现
  3. 「Vueconf」探索 Vue3 中 的 JSX
  4. OpenCV显示中文汉字,未使用CvxText和FreeType库
  5. YUI3下widget的plugin开发
  6. Java web 第一天
  7. gis投影中未定义的地理转换_PhotoScan中经纬度转换为投影坐标快捷方法
  8. iis启动服务时提示在本地计算机 无法启动iis admin服务,iis 依存服务和组没法启动...
  9. arpu计算方法、pv、uv、ip的意思
  10. 英语四级和计算机一级算多少学分,英语四级成绩怎么算分 多少分合格
  11. Chrome下载文件,文件名出现乱码解决
  12. java动物继承_java 编码实现动物世界的继承关系:动物(Animal)属性:名称(name)具有行为:吃(eat)、睡觉(sleep)...
  13. 定时开关机实现原理-Android4.4/6.0
  14. java实训第二次作业//181021(个人所得税计算器;判断闰年与平年;个人作业展示系统(方法调用))
  15. 缺芯导致全球汽车减产超一千万辆
  16. xhci键盘linux,QEMU “vmstate_xhci_event” 漏洞
  17. datastage 函数_DataStage常用函数大全.doc
  18. Iterm2保存服务器账密
  19. 关于电磁转矩这篇文章不错
  20. Android QQ空间浏览图片动画特效的实现(※)

热门文章

  1. RouterOS NAT伪装上网,NAT端口映射,HotspotWEB认证上网等的简单配置
  2. blogs博客系统项目介绍
  3. plant simulation物流系统仿真案例
  4. IEEE754数据格式介绍和解析方式(超权威)
  5. string教程c语言,C++ string类详解
  6. 项目之网易游戏官网-合作产品部
  7. 驱动阿里云的高性能网络引擎- 飞天洛神 1
  8. 【Python】difflib 文本比较,差异对比库
  9. 联想天逸F41a重装win7 x64
  10. 电脑计算机管理声音,教你如何解决电脑声音不正常