美文网首页
2021-01-31 今日主题 并发

2021-01-31 今日主题 并发

作者: 竹blue | 来源:发表于2021-02-01 08:39 被阅读0次

    今日主题 并发

    1.并行和并发有什么区别?

    并行:多个处理器或多核处理器同时处理多个任务。

    并发:多个任务在同一个 CPU 核上,按细分的时间片轮流(交替)执行,从逻辑上来看那些任务是同时执行。

    如下图:

    并发 = 两个队列和一台咖啡机。

    并行 = 两个队列和两台咖啡机。

    2.线程和进程的区别?

    一个程序下至少有一个进程,一个进程下至少有一个线程,一个进程下也可以有多个线程来增加程序的执行速度。

    3.创建线程有哪几种方式?

    创建线程有三种方式:

    继承 Thread 重写 run 方法;

    实现 Runnable 接口;

    实现 Callable 接口。

    4.线程有哪些状态?

    线程的状态:

    NEW 尚未启动

    RUNNABLE 正在执行中

    BLOCKED 阻塞的(被同步锁或者IO锁阻塞)

    WAITING 永久等待状态

    TIMED_WAITING 等待指定的时间重新被唤醒的状态

    TERMINATED 执行完成

    5.sleep() 和 wait() 有什么区别?

    类的不同:sleep() 来自 Thread,wait() 来自 Object。

    释放锁:sleep() 不释放锁;wait() 释放锁。

    用法不同:sleep() 时间到会自动恢复;wait() 可以使用 notify()/notifyAll()直接唤醒。

    6.notify()和 notifyAll()有什么区别?

    notifyAll()会唤醒所有的线程,notify()之后唤醒一个线程。notifyAll() 调用后,会将全部线程由等待池移到锁池,然后参与锁的竞争,竞争成功则继续执行,如果不成功则留在锁池等待锁被释放后再次参与竞争。而 notify()只会唤醒一个线程,具体唤醒哪一个线程由虚拟机控制。

    1. 线程的 run() 和 start() 有什么区别?

    start() 方法用于启动线程,run() 方法用于执行线程的运行时代码。run() 可以重复调用,而 start() 只能调用一次。

    1. 在 Java 程序中怎么保证多线程的运行安全?

    · 方法一:使用安全类,比如 Java. util. concurrent 下的类。

    · 方法二:使用自动锁 synchronized。

    · 方法三:使用手动锁 Lock。

    手动锁 Java 示例代码如下:

    Lock lock = new ReentrantLock();
    
    lock. lock();
    
    try {
    
      System. out. println(“获得锁”);
    
    } catch (Exception e) {
    
      // TODO: handle exception
    
    } finally {
    
      System. out. println(“释放锁”);
    
      lock. unlock();
    
    }
    

    9. 多线程中 synchronized 锁升级的原理是什么?

    synchronized 锁升级原理:在锁对象的对象头里面有一个 threadid 字段,在第一次访问的时候 threadid 为空,jvm 让其持有偏向锁,并将 threadid 设置为其线程 id,再次进入的时候会先判断 threadid 是否与其线程 id 一致,如果一致则可以直接使用此对象,如果不一致,则升级偏向锁为轻量级锁,通过自旋循环一定次数来获取锁,执行一定次数之后,如果还没有正常获取到要使用的对象,此时就会把锁从轻量级升级为重量级锁,此过程就构成了 synchronized 锁的升级。

    锁的升级的目的:锁升级是为了减低了锁带来的性能消耗。在 Java 6 之后优化 synchronized 的实现方式,使用了偏向锁升级为轻量级锁再升级到重量级锁的方式,从而减低了锁带来的性能消耗。

    1. 什么是死锁?

    当线程 A 持有独占锁a,并尝试去获取独占锁 b 的同时,线程 B 持有独占锁 b,并尝试获取独占锁 a 的情况下,就会发生 AB 两个线程由于互相持有对方需要的锁,而发生的阻塞现象,我们称为死锁。

    1. 怎么防止死锁?

    · 尽量使用 tryLock(long timeout, TimeUnit unit)的方法(ReentrantLock、ReentrantReadWriteLock),设置超时时间,超时可以退出防止死锁。

    · 尽量使用 Java. util. concurrent 并发类代替自己手写锁。

    · 尽量降低锁的使用粒度,尽量不要几个功能用同一把锁。

    · 尽量减少同步的代码块。

    1. ThreadLocal 是什么?有哪些使用场景?

    ThreadLocal 为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。

    ThreadLocal 的经典使用场景是数据库连接和 session 管理等。

    1. 说一下 synchronized 底层实现原理?

    synchronized 是由一对 monitorenter/monitorexit 指令实现的,monitor 对象是同步的基本实现单元。在 Java 6 之前,monitor 的实现完全是依靠操作系统内部的互斥锁,因为需要进行用户态到内核态的切换,所以同步操作是一个无差别的重量级操作,性能也很低。但在 Java 6 的时候,Java 虚拟机 对此进行了大刀阔斧地改进,提供了三种不同的 monitor 实现,也就是常说的三种不同的锁:偏向锁(Biased Locking)、轻量级锁和重量级锁,大大改进了其性能。

    14. synchronized 和 volatile 的区别是什么?

    · volatile 是变量修饰符;synchronized 是修饰类、方法、代码段。

    · volatile 仅能实现变量的修改可见性,不能保证原子性;而 synchronized 则可以保证变量的修改可见性和原子性。

    · volatile 不会造成线程的阻塞;synchronized 可能会造成线程的阻塞。

    1. synchronized 和 Lock 有什么区别?

    · synchronized 可以给类、方法、代码块加锁;而 lock 只能给代码块加锁。

    · synchronized 不需要手动获取锁和释放锁,使用简单,发生异常会自动释放锁,不会造成死锁;而 lock 需要自己加锁和释放锁,如果使用不当没有 unLock()去释放锁就会造成死锁。

    · 通过 Lock 可以知道有没有成功获取锁,而 synchronized 却无法办到。

    1. synchronized 和 ReentrantLock 区别是什么?

    synchronized 早期的实现比较低效,对比 ReentrantLock,大多数场景性能都相差较大,但是在 Java 6 中对 synchronized 进行了非常多的改进。

    主要区别如下:

    · ReentrantLock 使用起来比较灵活,但是必须有释放锁的配合动作;

    · ReentrantLock 必须手动获取与释放锁,而 synchronized 不需要手动释放和开启锁;

    · ReentrantLock 只适用于代码块锁,而 synchronized 可用于修饰方法、代码块等。

    · volatile 标记的变量不会被编译器优化;synchronized 标记的变量可以被编译器优化。

    反射

    1. 什么是反射?

    反射是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为 Java 语言的反射机制。

    1. 什么是 Java 序列化?什么情况下需要序列化?

    Java 序列化是为了保存各种对象在内存中的状态,并且可以把保存的对象状态再读出来。

    以下情况需要使用 Java 序列化:

    • 想把的内存中的对象状态保存到一个文件中或者数据库中时候;

    • 想用套接字在网络上传送对象的时候;

    • 想通过RMI(远程方法调用)传输对象的时候。

    1. 动态代理是什么?有哪些应用?

    动态代理是运行时动态生成代理类。

    动态代理的应用有 spring aop、hibernate 数据查询、测试框架的后端 mock、rpc,Java注解对象获取等。

    1. 怎么实现动态代理?

    JDK 原生动态代理和 cglib 动态代理。JDK 原生动态代理是基于接口实现的,而 cglib 是基于继承当前类的子类实现的。

    对象拷贝

    为什么要使用克隆?

    克隆的对象可能包含一些已经修改过的属性,而 new 出来的对象的属性都还是初始化时候的值,所以当需要一个新的对象来保存当前对象的“状态”就靠克隆方法了。

    1. 如何实现对象克隆?

    • 实现 Cloneable 接口并重写 Object 类中的 clone() 方法。
    • 实现 Serializable 接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆。

    Java Web

    1. JSP 和 servlet 有什么区别?

    JSP 是 servlet 技术的扩展,本质上就是 servlet 的简易方式。servlet 和 JSP 最主要的不同点在于,servlet 的应用逻辑是在 Java 文件中,并且完全从表示层中的 html 里分离开来,而 JSP 的情况是 Java 和 html 可以组合成一个扩展名为 JSP 的文件。JSP 侧重于视图,servlet 主要用于控制逻辑。

    1. JSP 有哪些内置对象?作用分别是什么?

    JSP 有 9 大内置对象:

    • request:封装客户端的请求,其中包含来自 get 或 post 请求的参数;

    • response:封装服务器对客户端的响应;

    • pageContext:通过该对象可以获取其他对象;

    • session:封装用户会话的对象;

    • application:封装服务器运行环境的对象;

    • out:输出服务器响应的输出流对象;

    • config:Web 应用的配置对象;

    • page:JSP 页面本身(相当于 Java 程序中的 this);

    • exception:封装页面抛出异常的对象。

    1. 说一下 JSP 的 4 种作用域?

    • page:代表与一个页面相关的对象和属性。
    • request:代表与客户端发出的一个请求相关的对象和属性。一个请求可能跨越多个页面,涉及多个 Web 组件;需要在页面显示的临时数据可以置于此作用域。
    • session:代表与某个用户与服务器建立的一次会话相关的对象和属性。跟某个用户相关的数据应该放在用户自己的 session 中。
    • application:代表与整个 Web 应用程序相关的对象和属性,它实质上是跨越整个 Web 应用程序,包括多个页面、请求和会话的一个全局作用域。
    1. session 和 cookie 有什么区别?

    • 存储位置不同:session 存储在服务器端;cookie 存储在浏览器端。
    • 安全性不同:cookie 安全性一般,在浏览器存储,可以被伪造和修改。
    • 容量和个数限制:cookie 有容量限制,每个站点下的 cookie 也有个数限制。
    • 存储的多样性:session 可以存储在 Redis 中、数据库中、应用程序中;而 cookie 只能存储在浏览器中。
    1. 说一下 session 的工作原理?

    session 的工作原理是客户端登录完成之后,服务器会创建对应的 session,session 创建完之后,会把 session 的 id 发送给客户端,客户端再存储到浏览器中。这样客户端每次访问服务器时,都会带着 sessionid,服务器拿到 sessionid 之后,在内存找到与之对应的 session 这样就可以正常工作了。

    相关文章

      网友评论

          本文标题:2021-01-31 今日主题 并发

          本文链接:https://www.haomeiwen.com/subject/lnddtltx.html