【线程基础篇】

news2025/7/21 10:58:19

进程

进程本质是一个正在执行的程序。程序运行时,系统会创建进程,并给进程分配独立的内存空间。

CPU时间片切换

CPU时间片切换时,进程需要从切换之前运行的位置开始执行,所以进程还包括程序计数器、堆栈指针。

单核CPU时,在任意时刻只会有一个进程被CPU调度。
操作系统利用CPU时间片切换,从宏观层面实现多应用并发。

在这里插入图片描述

线程

Java中本身不存在线程,线程是由操作系统提供的(Java -> JVM->OS操作系统)
在这里插入图片描述

线程的优势

1.在多核CPU中,多线程可以实现真正意义的并行。
2.一个应用进程中,不同任务由不同线程处理,避免任务顺序执行而引起的阻塞问题,提升程序的实时性。
3.线程可以认为是轻量级的进程,所以线程的创建、销毁比进程更快。
4.线程有独有的超线程技术,将一个物理CPU模拟成两个逻辑CPU,让单个物理CPU就能使用线程级的并行计算,但如果两个线程同时需要某个资源时,其中一个线程必须挂起,直到这些资源空闲以后才能继续。超线程技术能提升40%左右的性能。
5.线程的异步执行能更好的提升并发吞吐量。

线程的实现方式

继承Thread类
public class MyThread extends Thread { 
	public void run() { 
		System.out.println("MyThread.run()"); 
	} 
} 
MyThread myThread1 = new MyThread(); 
MyThread myThread2 = new MyThread(); 
//启动一个新线程去执行run(), start()内部调用的是一个native方法(private native void start0();)
myThread1.start();		
myThread2.start(); 

实现Runnable接口

public class MyThread implements Runnable { 
	public void run() { 
		System.out.println("MyThread.run()"); 
	} 
}

实现callable接口

public class TaskRunnableForDoc implements Callable<Boolean> {
    @Override
    public Boolean call(){
        try {
            //TODO
        }catch (Exception e){
            return false;
        }
        return true;
    }
}
public ThreadPoolTaskExecutor taskExecutor;
public void workForDoc(){
     try{
        Future<Boolean> future = taskExecutor.submit(new TaskRunnableForDoc());
        System.out.println(future.get());   //阻塞、获取返回值
     }catch (Exception e){
       e.printStackTrace();
     }
}

线程的生命周期

NEW

初始状态,线程被构建,但还没有调用start()。

RUNNABLED

运行状态,就绪和运行统称运行中

BLOCKED

阻塞状态(锁阻塞状态),线程放弃了CPU使用权,阻塞分以下几种:
等待阻塞
运行的线程执行wait(),JVM会把当前线程放入等待队列。
同步阻塞
运行的线程获取对象的同步锁时,如果同步锁被其他线程锁占用,JVM会把当前线程放入锁池。
其他阻塞
运行的线程执行Thread.sleep()或者thread.join()或者发出I/O请求时,JVM会把当前线程设置为阻塞状态,当sleep结束、join线程终止、IO处理完毕,则线程恢复。

WAITING
TIME_WAITING

超时等待状态,超时以后自动返回。

TERMINATED

终止状态。表示当前线程执行完毕。

线程状态代码示例

public class ThreadStatusDemo {
    public static void main(String[] args) {
      //TIME_WAITING
        new Thread(()->{
            while(true){
                try {
                    TimeUnit.SECONDS.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"Time_Waiting_Thread").start();

    //WAITING
        new Thread(()->{
            while(true){
                synchronized (ThreadStatusDemo.class) {
                    try {
                        ThreadStatusDemo.class.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        },"Wating_Thread").start();

    //BLOCKED
        new Thread(new BlockedDemo(),"Blocke01_Thread").start();
        new Thread(new BlockedDemo(),"Blocke02_Thread").start();
    }

    public static class BlockedDemo extends  Thread{
        @Override
        public void run() {
            synchronized (BlockedDemo.class){
                while(true){
                    try {
                        TimeUnit.SECONDS.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

运行之后,通过右击class文件,show in terminal
jps
在这里插入图片描述
jstack 15836

TIME_WAITING

在这里插入图片描述

WAITING

在这里插入图片描述

BLOCKED

在这里插入图片描述

线程的终止 interrupt

当子线程中有while(true) 之类无法中断的操作时,可以使用interrupt中断子线程。

stop

stop()结束一个线程时,并不保证线程的资源正常释放,stop()已经过期

thread.interrupt()

将thread线程的终止标识设置为true。通知thread终止线程,至于什么时候中断,取决于线程自己

Thread.currentThread().isInterrupted()

获取当前线程终止标识,默认false

Thread.currentThread().interrupted()

线程终止标识置为初始状态 : false

代码示例
public class InterruptDemo {
    public static void main(String[] args) throws InterruptedException {
        Thread thread=new Thread(()->{
            while(!Thread.currentThread().isInterrupted()){	//默认是false
             	// todo
            }
             // Thread.currentThread().interrupted(); 	//复位- 回到初始状态
        });
        thread.start();
        TimeUnit.SECONDS.sleep(1);
        thread.interrupt(); 	//把isInterrupted设置成true
    }
}

注意:sleep 通过InterruptedException 中断线程

守护线程

在Java线程中有两种线程,一种是用户线程,另一种是守护线程。
守护线程是一种特殊的线程,特殊指的是当进程中不存在用户线程时,守护线程会自动销毁。
典型的守护线程的例子就是垃圾回收线程,当进程中没有用户线程,垃圾回收线程就没有存在的必要了,会自动销毁。

public class Daemon {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new DaemonThread());
        thread.setDaemon(true); // 子线程设置成守护线程,当前用户进程运行结束,子线程自动销毁
        thread.start();
        Thread.sleep(10);
    }

    public static class DaemonThread implements Runnable {
        private int i;

        @Override
        public void run() {
            while (true) {
                i++;
                System.out.println(i);
            }
        }
    }
}

优先级

优先级分为1~10个级别,CPU会优先执行优先级较高的线程对象中的任务。如果设置优先级小于1或大于10,JDK抛出IllegalArgumentException。
JDK默认设置3个优先级常量,MIN_PRIORITY=1(最小值),NORM_PRIORITY=5(中间值,默认),MAX_PRIORITY=10(最大值)。
优先级具有继承性,比如线程A启动线程B,线程B的优先级与线程A是一样的。
优先级具有随机性,也就是说优先级高的线不一定每一次都先执行完成。

setPriority

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

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

相关文章

如何拼接字符串-探究“+号拼接”/“StringBuilder”在不同场景下的效率问题

拼接字符串&#xff0c;在程序开发中很常见也很常用&#xff0c;大家都会&#xff1a;号拼接String.concat(String str)StringBuffer / StringBuilder但这里今天主要探究“号拼接”&#xff0c;“StringBuilder”在不同场景下的效率问题。不都说 StringBuilder 在处理字符串拼接…

保持超低温环境新方法:功耗降至十分之一!

&#xff08;图片来源&#xff1a;网络&#xff09;量子比特是量子计算机的主要构建部分&#xff0c;然而热量会导致量子比特容易出错&#xff0c;因此量子系统通常保存在超低温稀释制冷机内&#xff0c;可以将温度保持在绝对零度&#xff08;−273.15℃&#xff09;以上。但是…

消费复苏迎“春”暖,服装行业如何开启“狂飙”模式?

2023年开年前2个月&#xff0c;全国多地消费市场的“热度”一直在持续上涨&#xff0c;商场、餐馆、娱乐场所等消费市场人气旺盛&#xff0c;消费复苏的“暖”意十足&#xff0c;一幕幕“忙”起来、“热”起来的场景&#xff0c;让各行各业的商家都对未来充满了期待与信心。在消…

基于SpringBoot的外卖项目的优化

基于SpringBoot的外卖项目的优化1、缓存优化1.1、缓存短信验证码问题分析代码改造1.2、缓存菜品数据实现思路1.3、Spring Cache介绍常用注解CachePutCacheEvictCacheable使用方式1.4、缓存套餐数据实现思路代码改造2、读写分离2.1、主从复制存在的问题介绍配置配置主库--master…

获取浏览器硬件资源的媒体数据(拍照、录音、录频、屏幕共享)

目录一、window.navigator 对象包含有关访问者浏览器的信息取二、MediaDevices1.使用麦克风2.使用摄像头&#xff08;和音频一样&#xff09;3.拍照4.录屏三、MediaRecorder(录制,可录制音频视屏)一、window.navigator 对象包含有关访问者浏览器的信息取 <!DOCTYPE html>…

YZRJ面试

面试过程目录概述需求&#xff1a;设计思路实现思路分析1.自我介绍之类的2.http 和https 协议的区别3.进程和线程的区别4.vm 安装的nginx 和Mysql5.评价拓展实现参考资料和推荐阅读Survive by day and develop by night. talk for import biz , show your perfect code,full bu…

自然语言处理(NLP)之求近义词和类比词<MXNet中GloVe和FastText的模型使用>

这节主要就是熟悉MXNet框架中的两种模型&#xff1a;GloVe和FastText的模型(词嵌入名称)&#xff0c;每个模型下面有很多不同的词向量&#xff0c;这些基本都来自wiki维基百科和twitter推特这些子集预训练得到的。我们只需要导入mxnet.contrib中的text模块即可&#xff0c;这里…

模拟百度翻译-课后程序(JAVA基础案例教程-黑马程序员编著-第六章-课后作业)

【案例6-5】 模拟百度翻译 【案例介绍】 1.任务描述 大家对百度翻译并不陌生&#xff0c;本案例要求编写一个程序模拟百度翻译。用户输入英文之后搜索程序中对应的中文&#xff0c;如果搜索到对应的中文就输出搜索结果&#xff0c;反之给出提示。本案例要求使用Map集合实现英…

C/C++开发,无可避免的内存管理(篇一)-约束好跳脱的内存

一、养成内存管理好习惯 1.1 养成动态对象创建、调用及释放好习惯 开发者手动接管内存分配时&#xff0c;必须处理这两个任务。分配原始内存时&#xff0c;必须在该内存中构造对象&#xff1b;在释放该内存之前&#xff0c;必须保证适当地撤销这些对象。如果你的项目是c项目&am…

windows、linux系统设置404教程(适用虚拟主机)

设置一个好的自定义错误页面&#xff0c;可以增加网站的收录&#xff0c;挽留住一些可能因打不开的页面而放弃的客户&#xff0c;我司虚拟主机特别提供了自定义错误页面设置&#xff0c;包括404错误在内的所有自定义错误都可以设置。 linux系统设置方法&#xff1a; 第一步:在…

mysql 内存架构

1. 背景 从 innodb 的整体架构中可以知道 innodb 的内存架构中分为 buffer pool 缓存区, change pool 修改缓冲区, adaptive hash index 自适应哈希索引, 和 log buffer 日志缓冲区. 2. buffer pool buffer pool 是用于缓冲磁盘页的数据&#xff0c;mysql 的80%的内存会分配给…

通过cfssl自签证书https证书

背景 公司内部自建Web服务&#xff0c;通过自签CA&#xff0c;然后签发https证书 工具地址: GitHub - cloudflare/cfssl: CFSSL: Cloudflares PKI and TLS toolkit 使用步骤: 1. 在release页面中下载最新的二进制包&#xff0c;我使用的是1.5的解压并重命名二进制文件 tar…

Idea集成码云

1&#xff1a;Idea集成码云1.1&#xff1a;IDEA安装码云插件【第一步】Idea 默认不带码云插件&#xff0c; 我们第一步要安装 Gitee 插件。如图所示&#xff0c; 在 Idea 插件商店搜索 Gitee&#xff0c;然后点击右侧的 Install 按钮。安装成功后&#xff0c;重启 Idea。Idea 重…

复旦团队发布国内首个模型MOSS 类ChatGPT

复旦团队发布国内首个模型MOSS 类ChatGPT 首先看到这个标题&#xff0c;还有这个名字&#xff0c;我是正经&#xff08;zhen jing&#xff09;的 &#xff08;bu shi 流浪地球&#xff1f;550W&#xff1f;不了解的可以把550W倒过来写&#xff0c;就懂了 看到新闻里的一些图…

Interview系列 - 07 Java | 集合的快速失败和安全失败机制 | 迭代器类源码 | CopyOnWriteArrayList

文章目录1. 集合的快速失败 (fail-fast)1. 使用增强for遍历集合并使用ArrayList的 remove() 方法删除集合元素2. 使用 forEach 遍历集合并使用ArrayList的 remove() 方法删除集合元素3. 使用迭代器遍历集合并使用ArrayList的 remove() 方法删除集合元素4. 使用迭代器遍历集合并…

人脑脊液的代谢组学研究—标识恶性神经胶质瘤的特征

百趣代谢组学分享&#xff0c;脑疾病病人的脑脊液&#xff08;CSF&#xff09;通常用来诊断和监测研究&#xff0c;但是恶性胶质瘤病人脑脊液组成的变化很少被人们所知。该研究作者建立了靶向代谢组学分析方法&#xff0c;采用SRM监测模式&#xff0c;使用正负离子切换的方法在…

MySQL实战之深入浅出索引(上)

1.前言 提到数据库&#xff0c;大家肯定会想到数据库的索引&#xff0c;很多人都知道索引是为了提高查询效率的&#xff0c;那么今天我就给大家讲一下&#xff0c;什么是索引&#xff0c;索引的数据结构是什么&#xff0c;索引是如何工作的。 因为索引的内容比较多&#xff0…

大数据应用要经得起考验,不可盲目跟风_光点科技

一项大数据应用&#xff0c;如果不是经得起推敲的&#xff0c;那就值得怀疑它是不是优秀的大数据应用&#xff0c;是不是有可利用的价值&#xff0c;是不是值得将人力物力财力花费在其中。所以&#xff0c;必须对大数据应用进行必要的筛选&#xff0c;做一定的检验之后才可以做…

vegfr2药物|适应症|市场销售数据-上市药品前景分析

癌症作为人类身体健康的主要威胁&#xff0c;其高死亡率一直是人类死亡的主要原因。尽管人类为控制癌症付出了巨大的努力&#xff0c;然而癌症的发病率和死亡率还是在高速增长。而肺癌、结直肠癌、肝癌和乳腺癌等被认为是癌症死亡的主要因素。而根据科研人员发现&#xff0c;癌…

JavaScript HTML DOM 简介

文章目录JavaScript HTML DOM 简介HTML DOM (文档对象模型)HTML DOM 树查找 HTML 元素通过 id 查找 HTML 元素通过标签名查找 HTML 元素通过类名找到 HTML 元素下面我们将学到如下内容JavaScript HTML DOM 简介 通过 HTML DOM&#xff0c;可访问 JavaScript HTML 文档的所有元素…