【Java面试】并发

news2024/9/22 15:44:53

文章目录

  • 线程有那些状态?
  • 一个程序来显示状态切换过程
    • 正常执行流程
    • 阻塞执行流程
    • 等待执行流程
  • 说说线程池的核心参数
  • wait和sleep的区别
  • Lock和synchronized的区别
  • Lock中Condition的使用
  • 说说Java中的悲观锁与乐观锁
    • 乐观锁
    • 悲观锁
  • Hashtable和ConcurrentHashMap的区别?
  • 【Java面试】谈一谈你对ThreadLocal的理解

线程有那些状态?

操作系统层面将线程状态分为5种,分别是:新建,就绪,运行,阻塞,死亡
但是在Java的Thread类中,线程的状态枚举如下:
在这里插入图片描述
也就是Java将线程分为了六种状态:创建,可运行,阻塞,等待,限时等待和终结
在这里插入图片描述
新建状态指的是我们使用new方法新建出来一个线程对象的时候,此时Java还没有将其与OS关联起来,那么这个线程就不会被分配CPU去执行代码,只有调用了start方法之后才会与真正的线程关联起来,此时就从新建状态变为了可运行(就绪)状态,等待分配CPU去执行任务,如果CPU分配给了当前线程,当前线程就会执行对应的任务,任务执行完毕之后,当前线程死亡(终结),注意是死亡,此时这个任务对应的线程以及资源都会被释放。
而并不是所有的任务都会被执行,因此会有部分任务进行阻塞,例如多线程访问同一个锁资源的时候,如果当前线程没有得到锁,那么当前线程就需要进行阻塞,此时CPU被分配给得到锁的线程去执行任务,任务执行完毕之后,锁释放,线程再次去争夺锁,得到锁的话就可以从阻塞状态变为可运行状态,此时只需要等待CPU分配资源就可以运行了。
而当前持锁线程可能执行任务后发现有些条件不满足,那么这个线程不能总是占有锁,因此可以选择调用wait方法去释放锁,然后让自己进入等待状态去等待条件的满足,此时其他线程就可以去竞争锁从而执行他们的任务,等到条件满足,就可以由另一个线程调用notify方法去提醒这个线程再次竞争锁去完成任务。
最后一种是等待的一种情况,叫做现时等待,也就是这次等待可以设定时间。
方法是使用wait方法并且设定等待的时间,再次之前如果时间到了或者另一个线程调用了notify方法,那么这个线程就会被唤醒。
还有一种是sleep方法,这种方法和wait不一样,sleep是不会释放当前线程的锁的,其他线程都得陪着这个线程等,这个线程等待完毕之后在继续执行接下来的任务,调用了sleep方法相对于是告诉CPU你现在先不用执行我的任务了,你可以先去干其他的,相当于让出CPU资源。

一个程序来显示状态切换过程

正常执行流程

首先来两个断点,一个断点打在主线程上,另一个断点打在分支上。
并且设定触发断点的条件为Thread,这样子我们进入debug状态之后就可以以线程作为操控条件了。
在这里插入图片描述
在这里插入图片描述
主线程断点设置在了最后一句,所以此时前面的语句都已经执行完毕了,但是由于还有一个断点打在了分支线程里面,所以如果我不让他执行,他就得等待
在这里插入图片描述
现在切换到分支线程执行语句
在这里插入图片描述
在这里插入图片描述
此时分支线程的任务已经执行完毕了,那么只有主线程还有任务了。
让主线程执行断点处的语句
在这里插入图片描述
可以发现在没有阻塞的情况下,线程状态为NEW->RUNNABLE->TERMINATED
这几个状态都是Thread类中定义的枚举类型。

阻塞执行流程

要让线程阻塞,就让他获取锁失败就行了
在这里插入图片描述
首先先创建线程,然后开启线程,但是不让线程执行任务
在这里插入图片描述
开启任务之后,先让分支线程执行一下,然后让他触碰到获取锁的位置但是先不执行,然后让主线程去执行获取锁的方法,然后再切换到分支线程去获取锁,此时分支线程获取锁失败,那么再让主线程打印分支线程的状态,此时的状态就是阻塞了。
之后主线程释放锁,分支线程继续执行任务,分支线程变为RUNNABLE状态,然后执行完成任务后死亡。
在这里插入图片描述

等待执行流程

大致流程也是差不多的,先让分支线程获取到锁,然后此时分支线程调用wait方法把锁让出去,那么主线程就能得到锁,然后查看此时分支线程的状态,主线程把分支线程唤醒之后,分支线程的状态从WAITTING变为了BLOCKING,因为此时分支线程要继续执行任务的话就需要获得锁。
得到锁之后继续重新执行任务,此时主线程发现分支线程的状态就是RUNNABLE了,然后分支线程执行完毕任务,死亡。
在这里插入图片描述

说说线程池的核心参数

线程池的执行流程也就是主线程(业务线程)提交任务到线程池之后,任务的处理流程。
下面来看execute方法
在这里插入图片描述
这个方法首先判断要执行的任务是否是空,如果是,返回一个空指针异常。否则,判断当前的工作线程数,如果工作线程数小于核心线程数,那么直接创建一个工作线程执行任务,如果不是,那么判断当前工作队列是否不满,如果是,那么将这个任务放入到工作队列中,如果不是,判断当前是否还有可用的非核心线程(判断maximumPoolSize-corePoolSize>0)即工作线程数是否大于最大线程数,如果不是,那么创建一个非核心线程来执行当前任务,如果是,那么就执行拒绝策略。流程图如下:
在这里插入图片描述

wait和sleep的区别

  • 共同点:
    wait(),wait(long)和sleep(long)的效果都是让当前线程暂时放弃CPU的使用权,进入阻塞状态
  • 方法归属不同
    sleep(long)是 Thread的静态方法
    而wait(),wait(long)都是Object的成员方法,每个对象都有,因此每一个对象都可以作为锁来调用这个方法
  • 醒来时机不同
    执行 sleep(long)和wait(long)的线程都会在等待相应毫秒后醒来
    wait(long)和 wait()还可以被notify唤醒,wait()如果不唤醒就一直等下去
    它们都可以被打断唤醒
  • 锁特性不同
    wait方法的调用必须先获取wait对象的锁,而sleep 则无此限制
    wait方法执行后会释放对象锁,允许其它线程获得该对象锁(我放弃,但你们还可以用),而sleep如果在 synchronized代码块中执行,并不会释放对象锁(我放弃,你们也用不了)

Lock和synchronized的区别

  • 语法层面
    synchronized是关键字,源码在jvm 中,用c++语言实现
    Lock是接口,源码由jdk 提供,用java语言实现
    使用synchronized时,退出同步代码块锁会自动释放,而使用Lock时,需要手动调用unlock方法释放锁
  • 功能层面
    二者均属于悲观锁、都具备基本的互斥、同步、锁重入功能
    Lock提供了许多synchronized不具备的功能,例如获取等待状态、公平锁、可打断、可超时、多条件变量
    Lock有适合不同场景的实现,如ReentrantLock,ReentrantReadWriteLock
  • 性能层面
    在没有竞争时,synchronized做了很多优化,如偏向锁、轻量级锁,性能不赖
    在竞争激烈时,Lock的实现通常会提供更好的性能

Lock中Condition的使用

说说Java中的悲观锁与乐观锁

1.悲观锁的代表是synchronized和Lock锁

  • 其核心思想是【线程只有占有了锁,才能去操作共享变量,每次只有一个线程占锁成功,获取锁失败的线程,都得停下来等待】
  • 线程从运行到阻塞、再从阻塞到唤醒,涉及线程上下文切换,如果频繁发生,影响性能
  • 实际上,线程在获取synchronized和Lock锁时,如果锁已被占用,都会做几次重试操作,减少阻塞的机会

2.乐观锁的代表是Atomiclnteger,使用cas来保证原子性

  • 其核心思想是【无需加锁,每次只有一个线程能成功修改共享变量,其它失败的线程不需要停止,不断重试直至成功】
  • 由于线程一直运行,不需要阻塞,因此不涉及线程上下文切换
  • 它需要多核cpu支持,且线程数不应超过cpu核数

乐观锁

乐观锁的典型操作就是CAS(compare and set)
这里按照乐观锁的要求,不加锁,每次失败的时候都重试,直到成功
当然,如果想要进行原子操作,需要保证共享变量的可见性,所以一般需要要求变量是volatile类型的。

public class SyncVsCas {
    static final Unsafe U = Unsafe.getUnsafe();
    //得到偏移位置
    static final long BALANCE = U.objectFieldOffset(Account.class,"balance");
    static class Account{
        volatile int balance=10;
    }

    public static void main(String[] args) {
        Account account = new Account();
        while (true) {
            int o = account.balance;
            int n = o+5;
            //第一个参数为:要修改的变量是那个对象的 第二个是偏移量
            //第三个参数为旧值  第四个参数为新值
            //这个方法会把o值和我们共享变量的值进行比对 如果一样那么就修改
            if(U.compareAndSetInt(account, BALANCE, o, n)){
                //原子性的
                break;
            }
        }
        System.out.println(account.balance);
    }
}

悲观锁

悲观锁就是很典型的使用synchronized

  public static void sync(Account account){
        Thread t1 = new Thread(()->{
            synchronized (account){
                int o = account.balance;
                int n = o-5;
                account.balance=n;
            }
        },"t1");
        Thread t2 = new Thread(()->{
            synchronized (account){
                int o = account.balance;
                int n = o+5;
                account.balance=n;
            }
        },"t2");
        t1.start();
        t2.start();
        System.out.println(account.balance);

    }

Hashtable和ConcurrentHashMap的区别?

【Java面试】谈一谈你对ThreadLocal的理解

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

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

相关文章

【玩转算法】(初始)动态规划

本期主题:动态规划,及其相关oj题。博客主页:小峰同学分享小编的在Linux中学习到的知识和遇到的问题小编的能力有限,出现错误希望大家不吝赐 🍁1)DP定义 动态规划是分治思想的延伸,通俗一点来说…

核酸检测预约系统毕业设计,核酸检测系统设计与实现,毕业设计怎么写论文毕设源码开题报告需求分析怎么做

项目背景和意义 目的:本课题主要目标是设计并能够实现一个基于web网页的疫情核酸检查预约系统,整个网站项目使用了B/S架构,基于java的springboot框架下开发;;通过后台设置医院信息、录入医院科室信息、录入医生信息、设…

CVE-2015-4852 Weblogic T3 反序列化分析

0x01 前言 看到很多师傅的面经里面都有提到 Weblogic 这一个漏洞,最近正好有一些闲暇时间,可以看一看。 因为环境上总是有一些小问题,所以会在本地和云服务器切换着调试 0x02 环境搭建 太坑了,我的建议是用本地搭建的方法&…

DeadObjectException解题

DeadObjectException解题 RemoteException occurs on reporting focusChanged, wWindow{2470935 u0 bundle_id/bundle_id.MainActivity}android.os.DeadObjectExceptionat android.os.BinderProxy.transactNative(Native Method)at android.os.BinderProxy.transact(Binder.ja…

十大开源测试工具和框架

免费的开源框架和工具由于其开源特性,现在逐渐成为自动化测试的首选解决方案。区别在于,你是喜欢使用类库编写一个全新的自动化测试框架,或者喜欢使用一个现成的工具。 本文帮忙你快速了解 10 大免费和开源测试工具、框架。 Katalon Studio…

【python】昔去雪如花,今来花似雪,今日份雪花快递到啦

前言 嗨喽~大家好呀,这里是魔王呐 ❤ ~ 大雪已至,冬天无恙,愿这个冬天的你,不缺暖阳,好日常在 小时候,冬天最盼望的就是下雪了~雪一下 在地上铺上一层雪白的毛毯的时候甚是好看~ 还能堆堆雪人、打打雪仗…

如何使用 django-import-export + pandas 在 Django 视图中导入 excel 数据

我想每个人都熟悉所有强大的库 django-import-export,它允许我们在 Django 的管理面板中导入和导出数据,但是如果你想让用户在网络上上传 excel 文件或通过 REST 上传它怎么办应用程序接口。最近,我遇到了类似的问题。经过大量研究,我找到了一种使用 Django 方式将数千个数…

基于jsp+mysql+ssm生鲜超市进销存管理系统-计算机毕业设计

项目介绍 目前超市越来越多,越来越普及,如何高效的管理经营超市才是成功的关键,其中对于中小型超市来说,在降低成本的前提下使用最有效的管理方式是非常重要的,所以开发中小型超市管理系统既考虑了成本相对较低又非常实用的特点。…

博客系统(前后端分离)

文章目录前言一、需求分析1.功能2.环境二、前端实现1.博客注册页2.博客登录页3.博客列表页4.博客详情页5.博客编辑页三、后端实现1.设计数据库表2.封装连接数据库的公共操作3.封装对博客表和用户表的操作4.实现博客列表页、博客详情页、博客编辑页的后端服务5.实现博客登录页面…

linux关于ssh免密登录、known_hosts文件

1. 关于ssh SSH 是 Secure Shell 的缩写,SSH 为建立在应用层基础上的安全协议。SSH 是目前广泛采用的安全登录协议,专为远程登录会话和其他网络服务提供安全性的协议,替代以前不安全的Telnet协议。利用 SSH 协议可以有效防止远程管理过程中的…

springboot车辆管理系统的设计与实现毕业社会源码031034

车辆管理系统的设计与实现 摘 要 科技进步的飞速发展引起人们日常生活的巨大变化,电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流,人类发展的历史正进入一个新时代。在现实运用中&…

java常量定义在interface和final class的区别?

问题现象: java常量定义在 interface 和 final class 的区别? 问题分析: 最近在项目开发规范中,发现有要求使用 interface类 来定义常量! 这让我想起来以前一直是用 final class 来定义常量的;那么这两者是…

【Eigen】Eigen库基础语法

这里是Eigen库的一些基础语法&#xff0c;摘自《视觉SLAM十四讲》&#xff0c;修改了书中代码的一些bug&#xff0c;部分地方添加了一些自己的理解。 头文件相关 #include <Eigen/Core> // Eigen 核心部分 #include <Eigen/Dense> // 稠密矩阵的代数运算&#xff…

Java - 通过反射进行赋值以及函数调用

Java - 通过反射进行赋值以及函数调用前言一. 通过反射进行赋值1.1 测试1.2 总结二. 通过反射进行函数调用前言 说来惭愧&#xff0c;虽然反射在Java中是非常重要和常见的一种机制。但是&#xff0c;每当自己去写这方面的代码的时候&#xff0c;总是容易愣住。还得想一想代码怎…

题库API搭建接口

题库API搭建接口 本平台优点&#xff1a;免费查题接口搭建 多题库查题、独立后台、响应速度快、全网平台可查、功能最全&#xff01; 1.想要给自己的公众号获得查题接口&#xff0c;只需要两步&#xff01; 2.题库&#xff1a;题库后台http://daili.jueguangzhe.cn/ 题库后台…

社招前端vue面试题汇总

用过pinia吗&#xff1f;有什么优点&#xff1f; 1. pinia是什么&#xff1f; 在Vue3中&#xff0c;可以使用传统的Vuex来实现状态管理&#xff0c;也可以使用最新的pinia来实现状态管理&#xff0c;我们来看看官网如何解释pinia的&#xff1a;Pinia 是 Vue 的存储库&#xff…

机器学习数据不均衡处理教程

机器学习数据不均衡处理教程 学习对数据进行过采样和欠采样、应用 SMOTE、集成方法和成本敏感型学习假设 课程英文名&#xff1a;Machine Learning with Imbalanced Data 此视频教程共13.5小时&#xff0c;中英双语字幕&#xff0c;画质清晰无水印&#xff0c;源码附件全 下…

Apriori算法及例题

一&#xff1a;Apriori算法介绍 关联规则挖掘是数据挖掘中最活跃的研究方法之一 。最早是由 Agrawal 等人提出的1993最初提出的动机是针对购物篮分析问题提出的&#xff0c;其目的是为了发现交易数据库中不同商品之间的联系规则。这些规则刻画了顾客购买行为模式&#xff0c;可…

Java去除文档阴影

Java去除文档阴影 一、前言 文稿扫描大家用的都比较频繁、想是各种证件、文件都可以通过扫描文稿功能保存到手机。相比直接拍照&#xff0c;在扫描文稿时&#xff0c;程序会对图像进行一些矫正。比如去除阴影、修正倾斜、旋转矫正等。进行这些处理后的图片要更加容易识别。今…

学习下c++原来它和Java有很多相似的地方

Java和CJava和C区别简单学习下C语法C 是什么&#xff1f;C工作原理&#xff1a;C标识符C基本数据类型C关键字封装&#xff0c;继承&#xff0c;多态简单回顾下Java语法Java的基础语法&#xff1a;Java注释Java标识符Java修饰符Java 接口和继承Java8 新增的特性Java和C区别 Java…