Android多线程学习:多线程同步

news2024/9/25 11:20:30

一、多线程

多线程就是指一个进程中同时有多个线程正在执行。

二、多线程优缺点:

优点
1、提高程序运行效率,如同时上传多个图片;
2、耗时操作放子线程执行,提高主线程执行效率,无需等待。

缺点
1、线程间切换,如果有大量的线程,会影响性能;
2、更多的线程需要更多的内存空间;
3、多线程操作可能会出现线程安全或者死锁等问题。

三、多线程同步方法:

线程的同步的意义在于线程安全,也就是说有多个线程并发访问同一个对象,而线程调度的不确定性可能带来潜在的安全问题。

1、同步函数
对于同步函数,其同步监视器是默认实例this

private synchronized void count() {
    if (count > 0) {
        Log.e(TAG, Thread.currentThread().getName() + "--->" + count--);
    } else {
        isRunning = false;
    }
}

2、同步代码块

 private void count() {
    synchronized (this) {
        if (count > 0) {
            Log.e(TAG, Thread.currentThread().getName() + "--->" + count--);
        } else {
            isRunning = false;
        }
    }
}

3、使用特殊域变量(volatile)实现线程同步

 private volatile int count = 1000;
  • volatile关键字为域变量的访问提供了一种免锁机制,
  • 使用volatile修饰域相当于告诉虚拟机该域可能会被其他线程更新,
  • 因此每次使用该域就要重新计算,而不是使用寄存器中的值
  • volatile不会提供任何原子操作,它也不能用来修饰final类型的变量

4、使用重入锁实现线程同步

  • ReentrantLock() : 创建一个ReentrantLock实例
  • lock() : 获得锁
  • unlock() : 释放锁
private void count() {
    lock.lock();
    if (count > 0) {
        Log.e(TAG, Thread.currentThread().getName() + "--->" + count--);
    } else {
        isRunning = false;
    }
    lock.unlock();
}

5、线程锁释放的几种情况

  • 当前线程的同步方法,同步代码块执行结束或者在执行中遇到breakreturn等终止了代码块的执行;
  • 同步代码块或者方法中出现未处理的Error或者Exception,导致异常结束;
  • 当前线程执行同步代码块或者同步方法时,程序中执行了同步监视器的wait()方法。

四、死锁:

指多线程因竞争资源而造成的一种僵局(互相等待),若无外力作用这些进程都将无法向前推进。

产生死锁的必要条件:

(1) 互斥条件:一个资源每次只能被一个进程使用。
(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

处理死锁的方法:

  • 预防死锁:这是一种较简单和直观的事先预防的方法。方法是通过设置某些限制条件,去破坏产生死锁的四个必要条件中的一个或者几个,来预防发生死锁。预防死锁是一种较易实现的方法,已被广泛使用。但是由于所施加的限制条件往往太严格,可能会导致系统资源利用率和系统吞吐量降低。

  • 避免死锁:该方法同样是属于事先预防的策略,但它并不须事先采取各种限制措施去破坏产生死锁的的四个必要条件,而是在资源的动态分配过程中,用某种方法去防止系统进入不安全状态,从而避免发生死锁。

  • 检测死锁:这种方法并不须事先采取任何限制性措施,也不必检查系统是否已经进入不安全区,此方法允许系统在运行过程中发生死锁。但可通过系统所设置的检测机构,及时地检测出死锁的发生,并精确地确定与死锁有关的进程和资源,然后采取适当措施,从系统中将已发生的死锁清除掉。

  • 解除死锁:这是与检测死锁相配套的一种措施。当检测到系统中已发生死锁时,须将进程从死锁状态中解脱出来。常用的实施方法是撤销或挂起一些进程,以便回收一些资源,再将这些资源分配给已处于阻塞状态的进程,使之转为就绪状态,以继续运行。死锁的检测和解除措施,有可能使系统获得较好的资源利用率和吞吐量,但在实现上难度也最大。

线程安全是以牺牲程序运行效率为代价的,因此在注意线程安全的同时,也要注意不要滥用锁和同步方法,尽量只对那些会改变竞争资源的方法进行同步。同时还要根据单线程和多线程运行环境来提供线程不安全和线程安全两种版本,JDK提供的StringBuilder,StringBuffer就是一个例子。

五、线程通信

1、wait() - 线程等待

  • 当前线程自动释放锁对象,线程进入等待状态(阻塞),直到其他线程调用了该锁的notify()或者notifyAll方法。在调用wait()之前,线程必须获得该对象的锁,因此只能在同步方法/同步代码块中调用wait()方法。

2、notify() - 线程唤醒

  • 唤醒在同一个锁对象等待的单个线程,若有多个线程等待,则任意选择其中一个。和wait()一样,notify()也要在同步方法/同步代码块中调用。

3、notifyAll() - 线程唤醒

  • 唤醒在此锁对象上等待的所有线程。
public class MainActivity extends AppCompatActivity {
    public static final String TAG = "test";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Object lock = new Object();

        Thread thread1 = new TestThread1(lock);
        thread1.start();
        Thread thread2 = new TestThread2(lock);
        thread2.start();
    }

    class TestThread1 extends Thread {
        private Object lock;

        private TestThread1(Object lock) {
            this.lock = lock;
        }

        @Override
        public void run() {
            try {
                synchronized (lock) {
                    Log.i(TAG, Thread.currentThread().getName() + "开始运行....");
                    lock.wait();
                    Log.i(TAG, Thread.currentThread().getName() + "结束运行....");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    class TestThread2 extends Thread {
        private Object lock;

        private TestThread2(Object lock) {
            this.lock = lock;
        }

        @Override
        public void run() {
            synchronized (lock) {
                Log.i(TAG, Thread.currentThread().getName() + "开始运行....");
                lock.notify();
                Log.i(TAG, Thread.currentThread().getName() + "结束运行....");
            }
        }
    }
}

运行结果:
wait1.PNG

参考文章:
Android线程管理之Thread使用总结
java多线程以及Android多线程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1074459.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Spring MVC研究】聊聊web绑定器(WebDataBinder、@InitBinder)

文章目录 1. 绑定器的作用2. 使用方式(测试代码)InitBinder3. 相关的几个核心类的真实类型4. 原理4.1. 正向推理4.2. 反向推理4.3. 正向反向推理结合分析4.4. 重点来了(如果前后衔接是接4.3章节)4.4.1. InitBinder注解的注册4.4.2…

vue学习-12路由组件的基本使用

vue的路由是vue,js官方的路由管理器,其主要用于构建单页应用程序,允许你通过定义路由来管理不同页面之间的导航。 1.引入路由 在使用vue的路由之前,一般我们在创建vue项目的时候,是可以选择添加路由的,只要你选择了y…

antd树型表格的逐级展开折叠(每次展开都只展开到当前未展开的最小层级,每次折叠都只折叠到当前未折叠的最大层级)

需求有些变态,我们用一段话和一张图来演示下 效果如下: 如遇到每级展开层级不一致的,如【2级2】展开到第3级,那此时点击展开,所有已展开的不动,将未展开到第3级的其他元素全部展开到第3级 效果如下&…

东土科技与诺贝尔物理学奖2006年度得主斯穆特签约,加快布局工业AI

近日,诺贝尔物理学奖2006年度得主乔治.斯穆特教授与东土科技正式签约,成为东土科技工业人工智能顾问。 乔治斯穆特(George Fitzgerald Smoot)教授也曾获得爱因斯坦奖,在宇宙学、大数据、生物医学诊断仪器以及人工智能…

第一章:随机过程预备知识

第一章:随机过程预备知识 随机过程属于概率论的分支学科。概率论注重结果:上涨的概率,下跌的概率。随机过程注重过程,随着时间的推移,结果的演化过程。 1.1 随机事件与概率的定义 事件的本质是集合,有关集…

workerman的基本用法(示例详解)

workerman是什么? Workerman是一个异步事件驱动的PHP框架,具有高性能,可轻松构建快速,可扩展的网络应用程序。支持HTTP,Websocket,SSL和其他自定义协议。支持libevent,HHVM,ReactPH…

朋友一口气拿下字节27K的offer,实名羡慕了....

最近有朋友去字节面试,面试前后进行了20天左右,包含4轮电话面试、1轮笔试、1轮主管视频面试、1轮hr视频面试。 据他所说,80%的人都会栽在第一轮面试,要不是他面试前做足准备,估计都坚持不完后面几轮面试。 其实&…

DRM全解析 —— framebuffer详解(1)

本文参考以下博文: Linux内核4.14版本——drm框架分析(1)——drm简介 特此致谢! 1. 简介 framebuffer是一块内存区域,可以理解为一块画布,驱动和应用层都能访问它。绘制前需要将它格式化,设定绘制的色彩模式&#x…

leetcode:217. 存在重复元素(python3解法)

难度:简单 给你一个整数数组 nums 。如果任一值在数组中出现 至少两次 ,返回 true ;如果数组中每个元素互不相同,返回 false 。 示例 1: 输入:nums [1,2,3,1] 输出:true 示例 2: 输…

DruidDataSource导致OOM问题处理

DruidDataSource导致OOM问题处理 起因分析日志分析Dump文件问题分析处理 起因 一个平凡的工作日,我像往常一样完成产品提出的需求的业务代码,突然收到了监控平台发出的告警信息。本以为又是一些业务上的 bug 导致的报错,一看报错发现日志写着…

Deepwalk,Node2vec算法原理生动理解(图文)

Deepwalk算法原理详解 DeepWalk算法之所以能够有效地学习节点的低维表示,是因为它利用了本质上与自然语言处理相同的思路:图是一种高维数据,很难直接处理,但是可以将其映射到低维空间中,这样可以更好地进行处理 Deep…

ElasticSearch 使用 searchAfter() 进行遍历查询 查到的数据总数小于 totalHits

ElasticSearch 使用 searchAfter() 进行遍历查询,查到的数据总数小于 totalHits,并且每次查询的页 size 越大,遍历总数和 totalHits 的差距越小。 原因 这是由于如下的机制: 每个文档具有一个唯一值的字段应该用作排序规范的仲裁…

2023 IDC中国数字金融论坛丨中电金信向行业分享“源启+应用重构”新范式

9月8日,IDC主办的“2023 IDC中国数字金融论坛”在北京召开。中电金信受邀参会,并带来了深度数字化转型趋势之下关于应用重构的分享与洞见。 论坛重点关注金融科技创新发展趋势与数字化转型之路,中电金信副总经理、研究院院长况文川带来了“创…

多无人机编队集群飞行

matlab2016b可直接运行 多无人机集群编队飞行(8架无人机)资源-CSDN文库

S7-1200PLC与力控通过S7协议进行通信的具体步骤示例

S7-1200PLC与力控通过S7协议进行通信的具体步骤示例 准备条件: TIA PORTAL V16 力控7.2 SP3 PLC:1214 DC/DC/DC PLC一侧的配置: PLC IP设置为192.168.2.10 PLC属性中的连接机制,勾选允许来自远程对象的PUT/GET 新建一个名为FirstDB的数据块,数据块编号为1 在FirstDB中添加…

大屏设计器项目部署详细步骤

一.项目效果图 二.部署步骤 1.nginx配置前端配置 #gzip on;server {listen 48009;server_name analyse;location / {root /home/designer/dist;index index.html;try_files $uri

vue中v-model的原理是什么?v-model作用在组件上的原理是什么?sync修饰符的原理是什么?

vue中v-model的原理是什么&#xff1f; 特点&#xff1a;双向绑定 数据>视图 视图>数据 场景&#xff1a; 收集表单数据组件上 原理&#xff1a; v-model只是个语法题&#xff0c;本质是&#xff1a;v-model v-bind (:value) v-on (input) <template><…

蓝牙资讯|三星推迟发布智能戒指Galaxy Ring,智能穿戴小型化是大趋势

根据外媒 The Elec 报道&#xff0c;Galaxy Ring这款戒指主要面向健康和 XR 头显市场&#xff0c;该智能戒指可能被延期至 2024 年第三季度后发布。 外媒声称三星 Galaxy Ring 的上市周期&#xff0c;主要取决医疗认证的相关审批时间&#xff0c;三星计划将在 2024 年第三季度…

2023年软件测试工具总结 —— 性能测试工具

软件性能测试的目标是识别应用程序中的所有性能瓶颈。一个软件系统的性能不仅取决于系统本身的设计和编码&#xff0c;而且取决于系统所依赖的运行环境。系统的运行环境会依赖于一些关键因素&#xff0c;例如&#xff1a;系统架构、硬件配置、网络带宽、配套的软件如数据库和中…

java多线程卖电影票的三种实现方式

java多线程卖电影票的三种实现方式 一、需求描述二、实现方式1、继承Thread类的方式2、实现Runnable接口的方式3、使用Lock锁的方式 一、需求描述 某电影院目前正在上映国产大片&#xff0c;共有1000张票&#xff0c;而它有2个窗口卖票&#xff0c;请设计一个程序模拟该电影院…