java并发编程面试问题和笔记

java并发编程面试问题和笔记

  • 问题
  • 基础

问题

  • 什么是死锁?如何避免死锁?
  • 什么是重排序?
  • volatile有哪些特性?
  • 什么是内存可见性?
  • volatile为什么能够保证内存可见性?
  • 中断机制
  • 线程通信有哪些方式?
  • 线程池的作用?
  • ThreadPoolExecutor如何使用?
  • 如何设置线程池的大小?
  • 如何保证线程安全?
  • JDK 1.6哪些对锁做了哪些优化?

#参考

  • https://juejin.im/post/5aa4a2e35188255589496eb8
  • https://blog.csdn.net/zhu2mu/article/details/60600618

基础

进程与线程

(1):进程是一个容器
(2):线程是这个容器中的工作单位

参考:http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html

操作系统基本原理

总结如下:

  • 以多进程形式,允许多个任务同时运行
  • 以多线程形式,允许单个任务分成不同的部分运行
  • 提供协调机制,一方面防止进程之间和线程之间产生冲突,另一方面允许进程之间和线程之间共享资源

参考:https://chyyuu.gitbooks.io/ucorebook/content/zh/cover/cover.html

#第三章:对象的共享

###3.1.3加锁与可见性

加锁的含义不仅仅局限于互斥行为,还包括内存可见性。为了确保所有线程都能看到共享变量的最新值,所有执行读操作或者写操作的线程都必须在同一个锁上同步

  • 确保某个线程写入该变量的值对于其他的线程来说都是可见的
  • 如果一个线程在未持有正确锁的情况下读取某个变量,那么读到的可能是一个失效值

###3.1.4Volatile变量

Volatile变量确保将变量的更新操作通知到其它线程。

加锁机制既可以确保可见性又可以确保原子性,而volatile变量只能确保可见性

当且仅当满足以下条件时,才可以使用volatile变量:

  • 对变量的写入操作不依赖变量的当前值,或者你能确保只有单个线程更新变量的值
  • 该变量不会与其他状态变量一起纳入不变性条件中
  • 在访问变量时不需要加锁

##3.3线程封闭

访问共享的可变数据时,需要使用同步。

  • 避免使用同步的方式就是不共享数据。如果仅在单线程内访问数据,就不需要同步,这被称为线程封闭。

###3.3.3ThreadLocal类

它使得线程中的某个值与保存值的对象关联起来,提供了get与set等访问接口或者方法,这些方法为每个使用该变量的线程都存有一份独立的副本,因此get总是返回由当前执行线程在调用set时设置的最新值。
一般用于防止对可变的单实例变量(Singleton)或者全局变量进行共享

##3.4不变性

前面提到的所有的问题都与多线程试图同时访问同一个可变的状态相关。如果对象的状态不会改变,那么这些问题与复杂性自然而然就消失了。

不可变对象一定是线程安全的

当满足下列条件之后,对象才是不可变的:

对象创建以后其状态就不能修改
对象的所有域都是final类型
对象是正确创建的(创建期间,this引用没有逸出)

#第十章:避免活跃性危险

##10.1死锁

每个人都拥有其它人需要的资源,同时又等待其它人已经拥有的资源,并且每个人在获得所有需要的资源之前都不会放弃已经拥有的资源。

多个线程相互等待已经被对方占用的资源时,就会发生死锁。

JVM解决方法:在一组Java线程发生死锁时,这些线程永远不能再继续使用了。恢复应用程序的唯一方式就是中止并重启他,并希望不要再发生同样的事情。

###10.1.1锁顺序死锁

即存在嵌套调用锁

A:锁住left,希望锁住right
B:锁住right,希望锁住left

如果所有线程以固定的顺序来获得锁,那么在程序中就不会出现锁顺序死锁问题。

###10.1.2动态的锁顺序死锁

虽然不存在方法A、B的相互调用但是假设线程A和线程B在进行X转账给Y,Y转账给X的任务是就有可能发生死锁。

###10.1.3在协作对象之间发生的死锁

###10.1.4开放调用

###10.1.5资源死锁

##10.2死锁的避免与诊断

  • 如果每个程序每次至多只能获得一个锁,那么就不会产生锁顺序死锁。
  • 如果必须获得多个锁,那么在设计时必须考虑锁的顺序:尽量减少潜在的加锁交互数量。

如何诊断:

  • 首先找出在什么地方将获取多个锁(使这个集合尽量小)
  • 然后对所有这些实例进行全局分析
  • 从而确保它们在整个过程中获取锁的顺序都保持一致

##10.2.1支持定时的锁

显式的使用Lock类中的定时tryLock功能来代替内置锁机制。

当使用内置锁时,只要没有获得锁,就会永远的等待下去
显式锁可以指定一个超时时限(Timeout),在等待超过该时间后tryLock会返回一个失败的信息

你可能感兴趣的:(Java)