Java 多线程(下)

九、创建线程池有哪几种方法?

  • newFixedThreadPool(int nThreads):创建一个固定长度的线程池,每当提交一个任务就创建一个线程,直到达到线程池的最大数量,这时线程规模将不再变化,当线程发生未预期的错误而结束时,线程池会补充一个新的线程。
  • newCachedThreadPool():创建一个可缓存的线程池,如果线程池的规模超过了处理需求,将自动回收空闲线程,而当需求增加时,则可以自动添加新线程,线程池的规模不存在任何限制。
  • newSingleThreadExecutor():这是一个单线程的Executor,它创建单个工作线程来执行任务,如果这个线程异常结束,会创建一个新的来代替它,它的特点是能确保依照任务在队列中的顺序来串行执行。
  • newScheduledThreadPool(int corePoolSize):创建了一个固定长度的线程池,而且以延迟或定时的方式来执行任务,类似于Timer。

十、线程池都有哪些状态?

线程池有五种状态:Running、ShutDown、Stop、Tidying、Terminated。

十一、线程池中submit() 和 execute() 方法有什么区别?

  • 接收的参数不一样
  • submit 有返回值,而 execute 没有
  • submit 方便 Exception 处理

十二、在 java 程序中怎么保证多线程的运行安全?

线程安全体现在三个方面:

  • 原子性:提供互斥访问,同一时刻只能有一个线程对数据进行操作(atomic,synchronized)
  • 可见性:一个线程对主内存的修改可以及时地被其他线程看到(synchronized,volatile)
  • 有序性:一个线程观察其他线程中地指令执行顺序,由于指令重排序,该观察结果一般杂乱无序(happens before原则)

十三、什么是死锁?

死锁是指两个或者两个以上地进程在执行过程中,由于竞争资源或者由于彼此通信而造成地一种阻塞地现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。是操作系统层命的一个错误,是进程死锁的简称,最早在 1965 年在研究银行家算法时提出的,它是计算机操作系统乃至整个并发程序设计领域最难处理的问题之一。

十四、怎么防止死锁?

死锁的四个必要条件:

  • 互斥条件:进程对所分配到的资源不允许其他进程进行访问,若其他进程访问该资源,只能等待,直至占有该资源的进程使用完成后释放该资源。
  • 请求和保持条件:进程获得一定的资源之后,又对其他资源发出请求,但是该资源可能被其他进程占有,此次请求阻塞,但又对自己获得的资源保持不放。
  • 不可剥夺条件:是指进程已获得的资源,在未完成使用之前,不可被剥夺,只能在使用完成后自己释放。
  • 环路等待条件:是指进程发生死锁后,若干进程之间形成一种头尾相接的循环等待资源关系。

这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要四个条件之一不满足,就不会发生死锁。

十五、ThreadLocal 是什么?有哪些使用场景?

线程局部变量是局限于线程内部的变量,属于线程自身所有,不在多个线程间共享。Java 提供ThreadLocal 类来支持线程局部变量,是一种实现线程安全的方式。但是在管理环境下(如web服务器)使用线程局部变量的时候要特别小心,在这种情况下,工作线程的生命周期比任何应用变量的生命周期都要长,任何线程局部变量一旦在工作完成后没有释放,Java应用就存在内存泄漏的风险。

十六、说一下 sychronized 底层实现原理?

sychronized 可以保证方法或者代码块在运行时,同一时刻只有一个方法可以进入到临界区,同时它还可以保证共享变量的内存可见性。

Java中每一个对象都可以作为锁,这是sychronized 实现同步的基础:

  • 普通同步方法,锁的是当前实例对象。
  • 静态同步方法,锁的是当前类的class对象。
  • 同步方法块,锁的是括号里面的对象。

十七、sychronized 和 volatile 的区别是什么?

  • volatile 本质是在告诉 jvm 当前变量在寄存器(工作内存)中的值是不确定的,需要从主内存中读取,synchronized 则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。
  • volatile 仅能使用在变量级别,sychronized 则可以使用在变量、方法和类级别的。
  • volatile 仅能实现变量的修改可见性,不能保证原子性,而 synchronized 则可以保证变量的修改可见性和原子性。
  • volatile 不会造成线程的阻塞,synchronized 可能会造成线程的阻塞。
  • volatile 标记的变量不会被编译器优化,sychronized 标记的变量可以被编译器优化。

十八、sychronized 和 Lock 有什么区别?

  • 首先 synchronized 是java内置关键字,在jvm层面,Lock是个java类。
  • synchronized 无法判断是否获取锁的状态,Lock可以判断是否获取到锁。
  • synchronized 会自动释放锁(a线程执行完同步代码会释放锁,b线程执行过程中发生异常会释放锁)Lock需要在finally中手工释放锁(unlock()方法释放锁),否则容易造成线程死锁。
  • 用synchronized 关键字的两个线程1和线程2,如果当前线程1获得锁,线程2等待,如果线程1阻塞,线程2则会一直等待下去,而Lock锁就不一定会等待下去,如果尝试获取不到锁,线程可以不用一直等待就结束了。
  • sychronized 的锁可重入、不可中断、非公平,而Lock锁可重入、可判断、可公平。
  • Lock锁适合大量同步的代码的同步问题,synchronized 锁适合代码少量的同步问题。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值