并发编程.

news2024/9/19 10:55:31

1、概述

1.1 进程和线程

进程:操作系统资源分配的最小单位。

  • 程序由指令和数据组成,指令要执行,数据要读写,就必须将指令加载至cpu,数据加载至内存,在指令运行过程中还需要用到磁盘、网络等设备,进程就是用来加载指令、管理内存、管理io的。
  • 当一个程序被运行,从磁盘加载这个代码至内存,这时就开启了一个进程。

线程:处理器任务调度和执行的最小单位。

  • 一个进程之内可以分为一到多个线程
  • 一个线程就是一个指令流,将指令流中的指令以一定的顺序交给cpu执行

区别

  • 进程基本上相互独立,线程存在于进程内,是进程的一个子集
  • 进程拥有共享的资源,如内存空间等,供其内部的线程共享
  • 进程间的通信:同一台计算机的进程通信称为IPC,不同计算机之间的进程通信,需要通过网络,并遵守共同的协议,如HTTP协议
  • 线程间通信比较简单,因为他们共享进程内的内存
  • 线程更轻量,线程上下文切换成本一般比进程上下文切换低

1.2 并发和并行

  • 并发
    同一时间应对多件事情的能力

单核cpu下,线程实际还是串行执行的,任务调度器将cpu的时间片分给不同的线程使用,只是由于cpu在线程间的切换时间非常快,给人感觉同时运行,微观串行,宏观并行,cpu的这种做法称为并发

  • 并行
    同一时间处理多件事情的能力

1.3 应用

单核仍是串行,多核才有意义

  • 异步调用
  • 提高效率

2、线程

2.1 创建线程

  • 使用Thread
@Slf4j
public class Test01 {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(){
            @Override
            public void run() {
                log.info("thread is run");
            }
        };
        thread.start();
    }
}
  • 使用Runnable
@Slf4j
public class Test01 {
    public static void main(String[] args) throws InterruptedException {
        Runnable runnable = ()-> log.info("thread is run");
        Thread thread = new Thread(runnable);
        thread.start();
    }
}
  • 使用Callable+FutureTask
@Slf4j
public class Test01 {
    public static void main(String[] args) throws InterruptedException {
        Callable<String> callable = () -> {
            log.info("thread is run");
            return "success";
        };
        FutureTask<String> futureTask = new FutureTask<>(callable);
        Thread thread = new Thread(futureTask);
        thread.start();
    }
}

2.2 查看线程

  • windows

任务管理器
tasklist 查看进程
taskkill 杀死进程

  • linux

ps -ef 查看所有进程
ps -fT -p 查看某个进程的所有线程
kill 杀死进程
top 按大写H切换是否显示线程
top -H -p 查看某个进程的所有线程

  • java

jps 查看所有java进程
jstack 查看进程的所有线程
jconsole

2.3 线程运行原理

  • 栈与栈帧
  • 每个栈由多个栈帧组成,对应着每次方法调用时所占的内存
    每个线程只能有一个活动栈帧,对应着当前正在执行的那个方法
  • 线程上下文切换
  • 线程的cpu时间片用完
    垃圾回收
    有更优先级的线程需要运行
    线程自己调用了sleep、yield、wait、join、park、synchronized、lock等方法
    当上下文切换时,由操作系统保存当前线程的状态,并恢复另一个线程的状态,java中对应的就是程序计数器,它的作用是记住下一条jvm指令的执行地址,它是线程私有的。

在这里插入图片描述

2.4 线程的使用

  • start & run
  • sleep & yeild
  • join
  • interrupt 打断
    打断sleep,wait,join的线程会抛出异常
@Slf4j
public class Test01 {
    public static void main(String[] args) throws InterruptedException {
        log.debug("enter main...");
        Thread t1 = new Thread(() -> {
            log.debug("t1 start...");
            while (true) {
                if (Thread.currentThread().isInterrupted()) {
                    log.debug("t1 exit...");
                    break;
                }
            }
        });
        t1.start();
        Thread.sleep(1000);
        log.debug("t1 start interrupt...");
        t1.interrupt();
        log.debug("" + t1.isInterrupted());
        log.debug("exit main...");
    }
}
  • park
@Slf4j
public class Test01 {
    public static void main(String[] args) throws InterruptedException {
       Thread t1 = new Thread(()->{
           log.debug("park...");
           LockSupport.park();
           log.debug("unpark...");
           log.debug("打断状态"+ Thread.interrupted());
           LockSupport.park();
           log.debug("unpark...");
       },"t1");
       t1.start();
       Thread.sleep(1000);
       t1.interrupt();
    }
}

2.5 守护线程

@Slf4j
public class Test01 {
    public static void main(String[] args) throws InterruptedException {
       Thread t1 = new Thread(()->{
           while (true){
               if(Thread.interrupted()){
                   break;
               }
           }
           log.debug("t1 end");
       },"t1");
       t1.setDaemon(true);
       t1.start();
       Thread.sleep(1000);
       log.debug("main end");
    }
}

2.6 线程的状态

2.6.1 分类

  • 按操作系统分
    在这里插入图片描述
  • 按java api分
    在这里插入图片描述

2.7 应用

异步调用: 主线程执行期间,其他线程异步执行耗时操作
提高效率: 并行计算,缩短运算时间
同步等待:join
统筹规划:合理使用线程,得到最优效果

2.7.1 两阶段终止模式

@Slf4j
public class Test01 {
    public static void main(String[] args) throws InterruptedException {
        TwoPhaseTermination twoPhaseTermination = new TwoPhaseTermination();
        twoPhaseTermination.start();
        twoPhaseTermination.stop();
    }
}

@Slf4j(topic = "TwoPhaseTermination")
class TwoPhaseTermination {
    private Thread monitor;

    public void start() {
        monitor = new Thread(() -> {
            Thread current = Thread.currentThread();
            while (true){
                if(current.isInterrupted()){
                    log.debug("料理后事");
                    break;
                }

                try {
                    Thread.sleep(1000);
                    log.debug("执行监控记录");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    current.interrupt();
                }
            }
        });
        monitor.start();
    }

    public void stop() {
        monitor.interrupt();
    }
}

2.7.2 统筹规划

在这里插入图片描述

@Slf4j
public class Test01 {
    public static void main(String[] args) throws InterruptedException {
       Thread t1 = new Thread(()->{
           try {
               log.debug("洗水壶");
               Thread.sleep(1);
               log.debug("烧开水");
               Thread.sleep(5);
           } catch (InterruptedException e) {
               e.printStackTrace();
           }

       },"小王");

        Thread t2 = new Thread(()->{
            try {
                log.debug("洗茶壶");
                Thread.sleep(1);
                log.debug("洗茶杯");
                Thread.sleep(2);
                log.debug("拿茶叶");
                Thread.sleep(1);
                t1.join();
                log.debug("泡茶");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"小张");
        t1.start();
        t2.start();
    }
}

3、并发-共享内存模型

3.1 管程-悲观锁(阻塞)

3.1.1 共享带来的问题

  • 临界区:
    一段代码块如果存在对共享资源的多线程读写操作,成这段代码块为临界区。在这里插入图片描述
  • 竞态条件
    多个线程在临界区内执行,由于代码的执行序列不同而导致结果无法预测,称之为发生了竞态条件

3.1.2 synchronized解决方案

  • 应用互斥
  • 阻塞式的解决方案:synchronized(俗称对象锁)、lock
  • 非阻塞式的解决方案:原子变量

synchronized实际是利用对象锁保证了临界区的原子性,临界区内的代码对外是不可分割的,不会被线程切换所打断

@Slf4j
public class Test01 {

    public static void main(String[] args) throws InterruptedException {
        LockTest lockTest = new LockTest();
       Thread t1 = new Thread(()->{
           for (int i = 0; i < 5000; i++) {
               lockTest.increment();
           }

       },"t1");

        Thread t2 = new Thread(()->{
            for (int i = 0; i < 5000; i++) {
                lockTest.decrement();
            }
        },"t2");
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(lockTest.get());
    }
}


class LockTest{
    private int count = 0;

    public void increment(){
        synchronized (this){
            count++;
        }
    }

    public void decrement(){
        synchronized (this){
            count--;
        }
    }

    public int get(){
        synchronized (this){
            return this.count;
        }
    }
}
  • 同步方法和静态同步方法的区别
    在这里插入图片描述

3.2 JMM

3.3 无锁-乐观锁(非阻塞)

3.4 不可变

3.5 并发工具

3.6 异步编程

4、并发-非共享模型

5、并行

6、应用

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

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

相关文章

python:并发编程(十八)

前言 本文将和大家一起探讨python并发编程的实际运用&#xff0c;会以一些我实际使用的案例&#xff0c;或者一些典型案例来分享。本文使用的案例是我实际使用的案例&#xff08;下篇&#xff09;&#xff0c;是基于之前效率不高的代码改写成并发编程的。让我们来看看改造的过…

计算逆波兰表达式

⭐作者介绍&#xff1a;大二本科网络工程专业在读&#xff0c;持续学习Java&#xff0c;努力输出优质文章 ⭐作者主页&#xff1a;逐梦苍穹 ⭐所属专栏&#xff1a;数据结构。数据结构专栏主要是在讲解原理的基础上拿Java实现 ⭐码云地址超链接(Gitee)&#xff1a;这里存放我学…

如何搭建Nginx网站服务

目录 一、首先搭建Nginx服务 二、授权的访问控制 第一步 安装依赖包 第二步 生成用户密码认证文件 第三步 修改文件属性和权限 第四步 修改配置文件 第五步 用浏览器测试网站 三、基于IP地址进行限制 第一步 修改配置文件 第二步 用两台设备进行访问测试 四、基于域…

工人规范操作识别系统 yolov5

工人规范操作识别系统通过yolov5python网络模型技术&#xff0c;工人规范操作识别系统对工人的操作进行实时监测&#xff0c;当工人规范操作识别系统检测到工人操作不符合规范时&#xff0c;将自动发出警报提示相关人员采取措施。YOLOv5中在训练模型阶段仍然使用了Mosaic数据增…

HCI-1

3.1 定义 就本文档而言&#xff0c;适用以下术语和定义&#xff1a; 嵌入式安全元件主机&#xff1a;在不可移动安全元件中实现的主机 门&#xff1a;主机内部运行的服务的入口点 主机&#xff1a;运行一项或多项服务的逻辑实体 主机控制器&#xff1a;还负责管理主机网络的…

聊聊 分布式系统 中的补偿机制设计问题

一、关于业务补偿机制 1、什么是业务补偿 2、业务补偿设计的实现方式 二、关于回滚 1、显示回滚 2、回滚的实现方式 三、关于重试 1、重试的使用场景 2、重试策略 3、重试时的注意事项 四、业务补偿机制的注意事项 1、ACID 还是 BASE 2、业务补偿设计的注意事项 我们知…

Langchain+本地大语言模型进行数据库操作的实战代码

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

Navicat Premium 16执行.sql语句中含有汉字乱码造成view和function创建后无法使用

Navicat Premium 16执行.sql语句中含有汉字乱码造成view和function创建后无法使用 如图&#xff0c;从这里选择sql时没法改sql。所以造成我昨天创建view和function时创建好的前面有感叹号没法用。打开一个fun看里面的汉字是问号。 所以要从这里打开&#xff1a; 1. ultraedit…

EMC学习笔记(十)特殊信号的EMC处理(二)

特殊信号的EMC处理&#xff08;二&#xff09; 1.对外接口的EMC设计标准电路1.1 DVI EMC设计标准电路1.2 HDMI接口EMC设计标准电路1.3 LVDS接口EMC设计标准电路1.4 PS2接口EMC设计标准电路1.5 RJ11 EMC设计标准电路1.6 SCART接口EMC设计标准电路1.7 s-video接口EMC设计标准电路…

五个步骤,助你优雅的写好 Controller 层代码!

Controller 层逻辑 普通写法 优化思路 Controller 层逻辑 MVC架构下&#xff0c;我们的web工程结构会分为三层&#xff0c;自下而上是dao层&#xff0c;service层和controller层。controller层为控制层&#xff0c;主要处理外部请求&#xff0c;调用service层。 一般情况下…

6.23黄金是否会跌破1900?多单被套怎么办?

近期有哪些消息面影响黄金走势&#xff1f;今日黄金多空该如何研判&#xff1f; ​黄金消息面解析&#xff1a;周四&#xff08;6月22日&#xff09;美市尾盘&#xff0c;现货黄金收报1910美元/盎司&#xff0c;下跌20美元或0.1%&#xff0c;日内最高触及1934.95美元/盎司&…

C++ 面向对象(1)——类 对象

C 在 C 语言的基础上增加了面向对象编程&#xff0c;C 支持面向对象程序设计。类是 C 的核心特性&#xff0c;通常被称为用户定义的类型。 类用于指定对象的形式&#xff0c;是一种用户自定义的数据类型&#xff0c;它是一种封装了数据和函数的组合。类中的数据称为成员变量&a…

Studio One6中文版多少钱?有哪些新功能

Studio One6中文版现在有三个版本&#xff0c;免费版&#xff0c;Artist&#xff0c;Pro版本。下载后是免费版&#xff0c;免费版没有时间限制&#xff0c;但是功能受限。三个版本都支持win/mac系统&#xff0c;而且同时支持5台设备使用&#xff0c;还可以换机使用。 三个版本…

Spring Cloud Day2 Nacos配置管理、Feign远程调用与Gateway服务网关

SpringCloud实用篇02 0.学习目标 1.Nacos配置管理 Nacos除了可以做注册中心&#xff0c;同样可以做配置管理来使用。 1.1.统一配置管理 当微服务部署的实例越来越多&#xff0c;达到数十、数百时&#xff0c;逐个修改微服务配置就会让人抓狂&#xff0c;而且很容易出错。我…

关闭 MAC 的 Microsoft AutoUpdate 自动更新

不是我说&#xff0c;这玩意儿看着是真不爽&#xff01;&#xff01;而且每天都要弹出来搞事情&#xff01;&#xff01;&#xff01; 我宣布&#xff1a;今天就要永久关闭 MAC 的 Microsoft AutoUpdate 自动更新&#xff01;&#xff01; 像我一样的朋友请举手&#xff01;&am…

Linux学习[17]bash学习深入3---万用字符特殊符号---数据流重导向

文章目录 前言1. 万用字符2. 特殊字符3. 数据流重导向3.1标准输出3.2 标准输入 总结 前言 这篇博客是对之前在查找的时候涉及到的一些通配符(bash里面就是万用字符)的整理。这个为后面管线相关打一个基础。 1. 万用字符 这里整理了一个表格&#xff0c;后面配上相关实例。 符…

定制化你的应用外观:gradio的自定义主题功能

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

Axure教程——多项选择器

本文介绍利用Axure里的中继器和动态面板制作一个多选下拉列表 一、效果 预览地址:https://frh0rc.axshare.com 二、功能 1、点击下拉框可以弹出选项&#xff0c;点击选项可以选中选项2、用户可以取消选中 三、制作 1、制作下拉框 拖入一个矩形组件&#xff0c;命名为“下拉框…

C++——指针空值

在良好的C/C编程习惯中&#xff0c;声明一个变量时最好给该变量一个合适的初始值&#xff0c;否则可能会出现不可预料的错误&#xff0c;比如未初始化的指针。如果一个指针没有合法的指向&#xff0c;我们基本都是按照如下方式对其进行初始化&#xff1a; void TestPtr() {int*…

python---案例分析(2)

例5: 使用python生成一个二维码 结果就会显示一个二维码!拿出手机扫描二维码就可以看到make中填写的内容! 例6: 操作excel 使用python计算平均分的情况 首先在自己的pycharm上安装xlrd 必须是上述版本的 安装成功版本后,import一下即可使用 以下是计算100班的平均分 例6: …