Android系统-线程-java线程

news2024/11/30 10:56:13

引言

Android的框架应用是java环境的。java天生就是多线程。所以对java线程的理解尤为重要。

概念

线程状态转换图

NEW 初始状态

RUNNABLE 运行状态

BLOCKED 阻塞状态

WAITING 等待状态

TIME_WAITING 超时等待状态

TERMINATED 终止状态

注意:调用obj.wait()的线程需要先获取obj的monitor,wait()会释放obj的monitor并进入等待态。所以wait()/notify()都要与synchronized联用。

阻塞与等待的区别

阻塞:当一个线程试图获取对象锁(非java.util.concurrent库中的锁,即synchronized),而该锁被其他线程持有,则该线程进入阻塞状态。就是说阻塞是一个线程因为等待临界区的锁被阻塞产生的状态。

它的特点是使用简单,由JVM调度器来决定唤醒自己,而不需要由另一个线程来显式唤醒自己,不响应中断。

等待:当一个线程等待另一个线程通知调度器一个条件时,该线程进入等待状态。

它的特点是需要等待另一个线程显式地唤醒自己,实现灵活,语义更丰富,可响应中断。例如调用:Object.wait()、Thread.join()以及等待Lock或Condition。等待 一个线程进入了锁,但是需要等待其他线程执行某些操作

主要方法

start()

新启一个线程执行其run()方法,一个线程只能start一次。主要是通过调用native start0()来实现。

public synchronized void start() {
//判断是否首次启动
        if (threadStatus != 0)
            throw new IllegalThreadStateException();

        group.add(this);

        boolean started = false;
        try {
//启动线程
            start0();
            started = true;
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                /* do nothing. If start0 threw a Throwable then
                  it will be passed up the call stack */
            }
        }
    }

    private native void start0();

run()

run()方法是不需要用户来调用的,当通过start方法启动一个线程之后,当该线程获得了CPU执行时间,便进入run方法体去执行具体的任务。注意,继承Thread类必须重写run方法,在run方法中定义具体要执行的任务。

sleep()

sleep方法有两个重载版本

sleep(long millis)     //参数为毫秒

sleep(long millis,int nanoseconds)    //第一参数为毫秒,第二个参数为纳秒

sleep相当于让线程睡眠,交出CPU,让CPU去执行其他的任务。

但是有一点要非常注意,sleep方法不会释放锁,也就是说如果当前线程持有对某个对象的锁,则即使调用sleep方法,其他线程也无法访问这个对象。

yield():调用yield方法会让当前线程交出CPU权限,让CPU去执行其他的线程。它跟sleep方法类似,同样不会释放锁。但是yield不能控制具体的交出CPU的时间,另外,yield方法只能让拥有相同优先级的线程有获取CPU执行时间的机会。

注意,调用yield方法并不会让线程进入阻塞状态,而是让线程重回就绪状态,它只需要等待重新获取CPU执行时间,这一点是和sleep方法不一样的。

join()

join方法有三个重载版本
 

join()
join(long millis)     //参数为毫秒
join(long millis,int nanoseconds)    //第一参数为毫秒,第二个参数为纳秒

join()实际是利用了wait(),只不过它不用等待notify()/notifyAll(),且不受其影响。它结束的条件是:1)等待时间到;2)目标线程已经run完(通过isAlive()来判断)。

public final synchronized void join(long millis) throws InterruptedException {
    long base = System.currentTimeMillis();
    long now = 0;

    if (millis < 0) {
        throw new IllegalArgumentException("timeout value is negative");
    }

    //0则需要一直等到目标线程run完
    if (millis == 0) {
        while (isAlive()) {
            wait(0);
        }
    } else {
        //如果目标线程未run完且阻塞时间未到,那么调用线程会一直等待。
        while (isAlive()) {
            long delay = millis - now;
            if (delay <= 0) {
                break;
            }
            wait(delay);
            now = System.currentTimeMillis() - base;
        }
    }
}

interrupt()

此操作会将线程的中断标志位置位,至于线程作何动作那要看线程了。

如果线程sleep()、wait()、join()等处于阻塞状态,那么线程会定时检查中断状态位如果发现中断状态位为true,则会在这些阻塞方法调用处抛出InterruptedException异常,并且在抛出异常后立即将线程的中断状态位清除,即重- 新设置为false。抛出异常是为了线程从阻塞状态醒过来,并在结束线程前让程序员有足够的时间来处理中断请求。
如果线程正在运行、争用synchronized、lock()等,那么是不可中断的,他们会忽略。
可以通过以下三种方式来判断中断:

isInterrupted()
此方法只会读取线程的中断标志位,并不会重置。
interrupted()
此方法读取线程的中断标志位,并会重置。
throw InterruptException
抛出该异常的同时,会重置中断标志位。

notify()

在Java中,notify()和notifyAll()都可以用于线程的唤醒,但它们有以下几个区别:

1. 唤醒数量不同

notify()方法只会随机唤醒等待队列中的一个线程,而notifyAll()方法则会唤醒等待队列中的所有线程。

2. 调用方式不同

notify()和notifyAll()方法都必须在同步代码块中调用,并且必须包含在synchronized块中,且必须是该对象的监视器对象才能够调用。而且只有在获取了锁之后才能调用,否则会抛出IllegalMonitorStateException异常。

3. 竞争情况不同

notify()方法只会唤醒等待队列中的一个线程,并使其与其他线程竞争获取锁,这可能会导致某些线程无法被唤醒或者一直处于等待状态。

notifyAll()方法则会唤醒等待队列中的所有线程,并使它们竞争获取锁,这样可以使所有线程都有机会获取锁并进入运行状态,从而避免了一些线程一直处于等待状态。

因此,在多线程编程中,如果需要唤醒所有等待该对象的线程,则可以使用notifyAll()方法;如果只需要随机唤醒一个等待该对象的线程,则可以使用notify()方法。
 

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

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

相关文章

AI大模型的使用-用LangChain链式调用简化多步提示语

众所周知&#xff0c;openAI的prompt对英文比较友好&#xff0c;也就是英文提示它的结果会更准确&#xff0c;假如我们不会英文&#xff0c;我们把中文问题给到OpenAI&#xff0c;然后让它翻译成英文&#xff0c;并把翻译后的英文给到OpenAI&#xff0c;让它帮忙给出解答问题&a…

【升职加薪秘籍】我在服务监控方面的实践(9)-报警设计

大家好,我是蓝胖子&#xff0c;关于性能分析的视频和文章我也大大小小出了有一二十篇了&#xff0c;算是已经有了一个系列&#xff0c;之前的代码已经上传到github.com/HobbyBear/performance-analyze&#xff0c; 接下来这段时间我将在之前内容的基础上&#xff0c;结合自己在…

干了外包3个月,技术退步明显...

先说一下自己的情况&#xff0c;大专生&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…

你觉得 Android 还有必要继续吗?

前言 这些年&#xff0c;总是听到有人说Android 开发岗位要凉了&#xff0c;不好做了。坦白说&#xff0c;市场倾向理性&#xff0c;竞争变强是很正常的事。但你发现总有些人&#xff0c;他们拿的 Offer 薪资是更高的&#xff0c;能达到年薪五六十万&#xff0c;甚至年薪百万。…

贪心算法总结篇

文章转自代码随想录 贪心算法总结篇 我刚刚开始讲解贪心系列的时候就说了&#xff0c;贪心系列并不打算严格的从简单到困难这么个顺序来讲解。 因为贪心的简单题可能往往过于简单甚至感觉不到贪心&#xff0c;如果我连续几天讲解简单的贪心&#xff0c;估计录友们一定会不耐…

房地产小程序制作要点:让你轻松搭建高效营销工具

近年来&#xff0c;随着房地产市场的不断发展和壮大&#xff0c;购房者对于房产信息的需求也日益增长。为了满足这一需求&#xff0c;许多开发商推出了看房预约小程序&#xff0c;以便让购房者更加方便快捷地了解房产信息并进行预约。然而&#xff0c;如何优化购房者体验&#…

论文阅读 FCOS: Fully Convolutional One-Stage Object Detection

文章目录 FCOS: Fully Convolutional One-Stage Object DetectionAbstract1. Introduction2. Related Work3. Our Approach3.1. Fully Convolutional One-Stage Object Detector3.2. Multi-level Prediction with FPN for FCOS3.3. Center-ness for FCOS 4. Experiments4.1. Ab…

重磅!TikTok将于8月底关闭半闭环 切断外链意在电商业务发展?

自2019年开始&#xff0c;TikTok电商业务逐渐走进人们的视线&#xff0c;并引起了市场的广泛关注。作为一家短视频平台&#xff0c;TikTok能够依靠其强大的用户基数与精准的推广策略&#xff0c;将流量成功转化为商业价值。截至目前&#xff0c;TikTok电商业务已经初步形成完整…

【Java】多线程(进阶)

多线程进阶 常见的所策略乐观锁和悲观锁重量级锁和轻量级锁自旋锁和挂起等待锁自旋锁挂起等待锁 读写锁和互斥锁读写锁互斥锁 公平锁和非公平锁公平锁非公平锁 可重入锁和不可重入锁可重入锁不可重入锁 CASCAS应用实现原子类实现自旋锁 CAS的ABA问题 synchronized原理基本特点加…

ATKck靶场系列二

信息收集 nmap -sP 192.168.111.0/24 nmap -sS -T4 -A -v -p- 192.168.111.80─# nmap -sS -T4 -A -v -p- 192.168.111.80 Starting Nmap 7.93 ( https://nmap.org ) at 2023-08-29 01:46 EDT NSE: Loaded 155 scripts for scanning. NSE: Script Pre-scanning. Initiating NS…

Linux之Shell(一)

Linux之Shell Shell概述Linux提供的Shell解析器bash和sh的关系Centos默认的解析器是bash Shell脚本入门脚本格式第一个脚本脚本常用的执行方式 变量系统预定义变量自定义变量特殊变量$n$#\$*、\$$? 运算符条件判断流程控制(▲)if判断case语句for循环while循环 read读取控制台输…

几种Go版本管理工具

缘起: 编译下面这段代码时,在Mac上没有什么问题,正常运行, 点击查看代码: package mainimport ( "bytes" "encoding/binary" "encoding/json" "fmt" "log" "math/rand" "net/http" "time")fu…

740212LD、740214、740214D、740214L比例插装线圈放大器

740212、740212D、740212L、740212LD、740214、740214D、740214L、740214LD、740228、740228D、740228L、740228LD、740612、740612D、740612L、740612LD、740614、740614D、740614L、740614LD线圈绕组采用N级(392 F [200 C]等级) 电磁线。 需要配对的电源线缆&#xff0c;该线…

ETC reset

ETC重新激活 换前挡风玻璃膜会把ETC设备拿下来&#xff0c;需要到【ETC服务中心】重新【粘上去】&#xff0c;另外需要工作人员用手持终端【重新激活】 ETC 背面有个 【白色】开关小柱子&#xff0c;一旦拆下来就失效&#xff0c;因为这个开关弹出来了 截面图看就是这样的&…

day 30 动态GDP柱状图绘制

列表.sort(key选择排序依据的函数&#xff0c;reverseTrue|False) 参数key:要求传入一个函数&#xff0c;表示将列表的每一个元素传入函数当中&#xff0c;返回排序的依据&#xff0c; 参数reverse,是否反转排序结果&#xff0c;True降序&#xff0c;False升序 my_list [[&…

linux下启动mysql不成功

最近在linux安装mysql数据库时&#xff0c;启动mysql&#xff0c;总是不成功&#xff0c;报如上所述问题&#xff0c;经过一番排查&#xff0c;最终是权限问题&#xff0c;将mysql目录下&#xff0c;统一修改为root权限。

C语言面向对象的编程思想

面向对象编程 面向对象编程Object-Oriented Programming&#xff0c;OOP&#xff09; 作为一种新方法&#xff0c;其本质是以建立模型体现出来的抽象思维过程和面向对象的方法。模型是用来反映现实世界中事物特征的。任何一个模型都不可能反映客观事物的一切具体特征&#xff0…

算法通过村第四关-栈黄金笔记|表达式问题

文章目录 前言1. 计算器问题2. 逆波兰表达式问题 总结 前言 提示&#xff1a;快乐的人没有过去&#xff0c;不快乐的人除了过去一无所有。 --理查德弗兰纳根《深入北方的小路》 栈的进阶来了&#xff0c;还记得栈的使用场景吗&#xff1f;表达式和符号&#xff0c;这不就来了 1…

杂记 23.8.30

目录 tesol专业介绍 EMBA项目 适合学习时候听的轻音乐 安全感和孤独感 puffy fix sb up with sth For all the world Size up 博雅、博雅教育 人是需要被仰视的 tesol专业介绍 tesol专业的全称是“Teaching English to Speakers of Other Language”&#xff0c;可译…

自动化管理管理工具----Ansible

目录 ​编辑 一、Ansible概念 1.1特点 二、工作机制&#xff08;日常模块&#xff09; 2.1 核心程序 三、Ansible 环境安装部署 四、ansible 命令行模块 4.1command 模块 4.2shell 模块 4.3cron 模块 4.4user 模块 4.5group 模块 4.6copy模块 4.7file模块 4.8ho…