JAVA多线程实现的四种方式
https://www.cnblogs.com/felixzh/p/6036074.html
线程池源码解析
https://blog.csdn.net/u010963948/article/details/80573898
什么是线程安全
当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以得到正确的结果,那这个对象就是线程安全的。
并发级别有哪几种
一、阻塞
当一个线程进入临界区后,其他线程必须等待 。
二、无障碍(Obstruction-Free)
无障碍是一种最弱的非阻塞调度
自由出入临界区
无竞争时,有限步内完成操作
有竞争时,回滚数据
三、无锁(Lock-Free)
是无障碍的
保证有一个线程可以胜出
四、无等待(Wait-Free)
无锁的
要求所有的线程都必须在有限步内完成
无饥饿的
Amdahl定律(阿姆达尔定律)
定义了串行系统并行化后的加速比的计算公式和理论上限
加速比定义:加速比=优化前系统耗时/优化后系统耗时
synchronized与static synchronized 的区别
synchronized是对类的当前实例进行加锁。
static synchronized是对类进行加锁。
Java并发的三个概念
原子性是指一个操作是不可中断的,要么全部执行成功要么全部执行失败。
可见性是指当一个线程修改了某一个共享变量的值,其他线程是否能够立即知道这个修改。
有序性是指如果在本线程内观察,所有的操作都是有序的;如果在一个线程观察另一个线程,所有的操作都是无序的。
什么是Unsafe类。
Unsafe类存在于sun.misc包中,其内部方法操作可以像C的指针一样直接操作内存,单从名称看来就可以知道该类是非安全的,毕竟Unsafe拥有着类似于C的指针操作,因此总是不应该首先使用Unsafe类,Java官方也不建议直接使用的Unsafe类,但我们还是很有必要了解该类,因为Java中CAS操作的执行依赖于Unsafe类的方法,注意Unsafe类中的所有方法都是native修饰的,也就是说Unsafe类中的方法都直接调用操作系统底层资源执行相应任务。
如何获取Unsafe类。
Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafeInstance.setAccessible(true);
// return (Unsafe) theUnsafeInstance.get(null);
//等价
return (Unsafe) theUnsafeInstance.get(Unsafe.class);
CAS操作中valueOffset的理解。
valueOffset为该字段(或引用类型)在实例对象中的偏移量。可以简单理解为指针指向该变量的内存地址。通过偏移量可以设置,获取该字段(或引用类型)的值。
volatile可不可以保证原子性?
volatile的语义不足以确保递增操作(count++)的原子性,因为它分为三步:1、读内存到寄存器;
2、在寄存器中自增;
3、写回内存。除非你能确保只有一个线程对变量执行写操作。
如何获取死锁线程?
private final static ThreadMXBean mxbean= ManagementFactory.getThreadMXBean();
long[] deadLockedThreadIds = mxbean.findDeadlockedThreads();
ThreadInfo[] threadInfos = mxbean.getThreadInfo(deadLockedThreadIds);
CyclicBarrier的reset()方法的使用?
正常情况下不需要使用reset(),CyclicBarrier的计数器会在所有线程到达集合点后自动重置,在一个run方法内可重复调用await()多次等待所有线程集合,而调用reset()会导致之后的await()方法调用时,发生BrokenBarrierException异常。
文章图片
1
文章图片
2
文章图片
3 【Java多线程笔记】
Locksupport的park()于suspend()的区别是什么?
假如有A,B两个线程,A线程在获得某个锁之后被suspend阻塞,这时A不能继续执行,线程B在或者相同的锁之后才能调用resume方法将A唤醒,但是此时的锁被A占有,B不能继续执行,也就不能及时的唤醒A,此时A,B两个线程都不能继续向下执行而形成了死锁。这就是suspend被弃用的原因。
而先使用unPark()再使用park()不会造成形成死锁。
park()能够响应中断,但不抛出异常。
中断响应的结果是,park()函数的返回,可以从Thread.interrupted()得到中断标志。
ForkJoinPool的Scan算法基本流程
文章图片
image.png
如何获取一个单例
public class StaticSingleton {
private StaticSingleton(){
System.out.println("StaticSingleton is create!");
}
privatestatic classSingletonHolder{
private static StaticSingleton instance = new StaticSingleton();
}
public static StaticSingleton getInstance(){
return SingletonHolder.instance;
}
}
锁优化的思路和方法
减少锁持有时间
减小锁粒度
锁分离
锁粗化
锁消除
StampedLock优化了哪些内容
StampedLock是Java8引入的一种新的所机制,简单的理解,可以认为它是读写锁的一个改进版本,读写锁虽然分离了读和写的功能,使得读与读之间可以完全并发,但是读和写之间依然是冲突的,读锁会完全阻塞写锁,它使用的依然是悲观的锁策略.如果有大量的读线程,他也有可能引起写线程的饥饿.
而StampedLock则提供了一种乐观的读策略,这种乐观策略的锁非常类似于无锁的操作,使得乐观锁完全不会阻塞写线程。