zoukankan      html  css  js  c++  java
  • [Android学习笔记]Android中多线程开发的一些概念

    线程安全:

    在多线程的情况下,不会因为线程之间的操作而导致数据错误。


    线程同步:

    同一个资源,可能在同一时间被多个线程操作,这样会导致数据错误。这是一个现象,也是一个问题,而研究如何解决
    此类问题的相关工作就叫做线程同步。

     

    android中,处理线程同步的手段就是:锁

    一般分为公平锁和非公平锁:

    synchronized(内部锁,互斥锁):
    synchronized是JVM提供的线程同步机制,如果出现问题,JVM能捕获异常,并释放资源,具体实现机制需要查看JVM源码

    synchronized的使用特点:


    lock接口:
    这些实现了lock接口的锁定义是通过java语言进行实现与封装的,具体的实现机制可以通过查看其源代码得知

    lock实例加锁和解锁的大概过程:
    当一个资源被锁定之后,访问它的线程会被加入等待队列,当

    内部锁(互斥锁)ReentrantLock
    读写锁


    synchronized
    1.synchronized作用在方法上:锁对象
    2.synchronized作用在代码块:只锁代码块
    3.synchronized(this):对象锁
    4.synchronized(object):成员锁

    总结synchronized:
    可以锁对象:synchronized(this) , synchronized(class) , synchronized methods , 此时对象的所有
    资源不能被其他线程访问

    成员锁:
    synchronized(obj){ } , 代码段内的代码不能被同时访问。

    对象锁太粗糙

    通常情况使用synchronized就够了,资源竞争很激烈的情况下,Synchronized的性能会下降几十倍,才会使用
    ReetrantLock来完成复杂的业务需求。(不公平锁)

    使用java封装的锁对象可以更灵活的满足业务需求,比如可以设定锁的等待时间,公平性等等,而使用Synchronized
    则只能使用同步监视器的三个方法来操作线程


     

    线程通讯:

    synchronized作为对象锁时候,通过this,可以调用三个方法在线程之间通讯
    synchronized作为成员所时候,通过(obj),调用三个方法,其中被锁的东西就叫做同步监视器。(this,obj)

    wait:当前线程进入等待状态,直到其他线程调用该同步监视器的notity方法或者notityall方法来唤醒.
    调用wait就以为着释放同步监视器

    notify:唤醒在此同步监视器上等待的单个线程。如果所有线程都在此同步监视器上等待,则会随机选择唤醒其中一个线程。
    只有当前线程放弃对该同步监视器的锁定后(用wait方法),才可以执行被唤醒的线程

    notityAll: 唤醒在此同步监视器上等待的所有线程。只有当前线程放弃对该同步监视器的锁定后,才能执行唤醒的线程。

     


     

    线程模型:
    消息循环
    消息队列
    handler
    Thread
    UI Thread

    android的线程模型:
    UI线程有一个消息队列,一个消息循环,一个Handler.

    一般建立的后台线程对象就是一个一次性完成工作的任务.

    如何建立他们之间的联系?

    一般情况下,启动一个非UI线程用于处理耗时工作之后,需要一个机制用于通知UI线程,工作做好了,
    这个机制就是一个Message。
    当后台线程工作结束之后,向欲通知的线程发送一个Message,用来通知这个目标线程说:“我已经工作完了”,而这个
    Message怎么发过去呢?通过Handler对象。 想给哪个线程发送Message就给该线程的Handler发送Message.
    (前提是目标线程有处理消息的能力)
    综上:

    当后台线程完成工作之后,会通过UI线程的Handler对象发送一个Message到UI线程的消息队列中,UI线程的消息循环
    就会从消息队列中取出此Message,并且处理此Message,做爱做的事。

    对于一个后台线程:

    如果想让该 线程具有消息队列和消息循环,需要在线程中首先调用Looper.prepare()来创建消息队列,然后调用Looper.loop()进入消息循环。 如下例所示:
    class LooperThread extends Thread {
    public Handler mHandler;

    public void run() {
    Looper.prepare();

    mHandler = new Handler() {
    public void handleMessage(Message msg) {
    // process incoming messages here
    }
    };

    Looper.loop();
    }
    }
    这样你的线程就具有了消息处理机制了,在Handler中进行消息处理。

     

     

  • 相关阅读:
    聊聊Flame Graph(火焰图)的那些事
    Dynamometer:HDFS性能扩展测试工具
    论分布式系统中单一锁控制的优化
    聊聊磁盘数据的损坏
    分级副本存储:一种更具效益成本的数据容错策略
    分布式存储系统中的Data Scrubbing机理
    论一个成熟分布式系统的工具类设计
    聊聊Raft一致性协议以及Apache Ratis
    ListenableFuture的状态同步和原子更新
    2018-9-1-win10-uwp-轻量级-MVVM-框架入门-2.1.5.3199
  • 原文地址:https://www.cnblogs.com/hellenism/p/3821356.html
Copyright © 2011-2022 走看看