2018年9月


撰写于    浏览:175 次  分类: 多线程与并发
对于下述单例模式,我们使用了两次判断,但是,编译器很有可能会认为第一次判断成功以后没有必要再去做第二次判断,因为编译器会认为instance的值在这两次判断之间并没有改变,编译器是不会去考虑另一个线程有没有来改变instance的值,它只看到这一段代码,但是这里的两次判断是有其作用的。public class Singleton { pri[...]

撰写于    浏览:259 次  分类: 多线程与并发,一针见血20点
现在的CPU一般采用流水线来执行指令。一个指令的执行被分成:取指、译码、访存、执行、写回等若干个阶段。多条指令可以同时存在于流水线中,同时被执行。指令流水线并不是串行的,并不会因为一个耗时很长的指令在"执行"阶段呆很长时间,而导致后续的指令都卡在"执行"之前的阶段上。相反,流水线是并行的,多个指令可以同时处于同一个阶段,只要CPU内部相应的处理部件[...]

撰写于    浏览:1187 次  分类: 多线程与并发,一针见血20点
在程序运行过程中,所有的变更会先在寄存器或本地cache中完成,然后才会被拷贝到主存以跨越内存栅栏,此种跨越序列或顺序称为happens-before。注:happens-before本质是顺序,重点是跨越内存栅栏通常情况下,写操作必须要happens-before读操作,即写线程需要在所有读线程跨越内存栅栏之前完成自己的跨越动作,其所做的变更才能[...]

撰写于    浏览:453 次  分类: 多线程与并发,一针见血20点
本文从简单入手,简单不代表肤浅,技术都是从简单发展起来的,然后变得复杂,甚至都偏离了初衷。有的人瞧不起简单,可不是什么好事啊。简单来说内存屏障(Memory Barrier,或内存栅栏,Memory Fence)就是从本地或工作内存到主存之间的拷贝动作。如下图:上面三种颜色的箭头,就是跨越内存栅栏。在多线程并发过程中,仅当写操作线程先跨越内存栅栏而[...]

撰写于    浏览:177 次  分类: 多线程与并发
大多数现代微处理器都会采用将指令乱序执行(out-of-order execution)的方法,在条件允许的情况下,直接运行当前有能力立即执行的后续指令,避开获取下一条指令所需数据时造成的等待。通过乱序执行的技术,处理器可以大大提高执行效率。除了处理器,常见的Java运行时环境的JIT编译器也会做指令重排序操作,即生成的机器指令与字节码指令顺序不一[...]

撰写于    浏览:16510 次  分类: 面试集锦
面试,是学习的动力。考题,是知识的升华。下面这些面试题目来在于一线大厂,包括BAT,网易,京东,小米、滴滴、头条、美团等企业的面试题目,大家看看自己有多少会的,有多少不会的。1 CPU核心数、线程数的关系2 在CPU时间片轮转机制中设置多少毫秒是合理的?3 什么是进程?什么是线程?一个进程最多可以创建多少个线程?4 用户单一进程同时可打开文件数量是[...]

撰写于    浏览:410 次  分类: 多线程与并发
计算机系统中,为了尽可能地避免处理器访问主内存的时间开销,处理器大多会利用缓存(cache)以提高性能。其模型如下图所示。在这种模型下会存在一个现象,即缓存中的数据与主内存的数据并不是实时同步的,各CPU(或CPU核心)间缓存的数据也不是实时同步的。这导致在同一个时间点,各CPU所看到同一内存地址的数据的值可能是不一致的。内存屏障(Memory B[...]

撰写于    浏览:1538 次  分类: 多线程与并发,一针见血20点
ThreadLocal类是修饰变量的,重点是在控制变量的作用域,初衷可不是为了解决线程并发和线程冲突的,而是为了让变量的种类变的更多更丰富,方便人们使用罢了。很多开发语言在语言级别都提供这种作用域的变量类型。根据变量的作用域,可以将变量分为全局变量,局部变量。简单的说,类里面定义的变量是全局变量,函数里面定义的变量是局部变量。还有一种作用域是线程作[...]