分类 一针见血20点 下的文章


撰写于    浏览:2134 次  分类: 多线程与并发,一针见血20点
应用程序这个词包括两个类别:应用和程序。应用面向的对象是人,程序面向的对象是CPU。应用=加班+框架,程序=数据结构+算法多线程与并发研究的本质就是在研究程序。

撰写于    浏览:716 次  分类: 多线程与并发,一针见血20点
数据在哪里存在呢?只在内存吗?不是的。数据在内存中存在,但是当用的时候会加载到CPU的寄存器里面。内存和寄存器是两个地方,从而出现了新的名词:内存可见性和寄存器可见性。为什么叫内存可见性呢?感觉很奇怪的名字。其实,明白以下道理就不奇怪了:数据的流动过程是:内存->寄存器->计算器很多时候,数据从内存地址读取到寄存器里面,后面的计算过程中[...]

撰写于    浏览:805 次  分类: 一针见血20点
synchronized代码块儿里面的变量都实现了内存可见性。内存可见性的底层是CPU的指令实现的。viotile修饰的是变量,它的作用也是实现内存可见性,底层用的用的同一个CPU指令。可以这样理解:synchronized里面的变量都是viotile修饰的。我们都用过synchronized,但是用viotile机会很少,其实换个角度想想,syn[...]

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

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

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

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

撰写于    浏览:2674 次  分类: 多线程与并发,一针见血20点
本文修订于2018年9月5日在Java中,通过下面的代码,我们可以很容易地获取到系统可用的处理器核心数目:Runtime.getRuntime().availableProcessors();基本原则是:应用程序的最小线程数应该等于可用的处理器核数。具体场景又分为以下两种情况:(1)如果所有的任务都是计算密集型的,则创建处理器可用核心数那么多个线程[...]

撰写于    浏览:38130 次  分类: 多线程与并发,一针见血20点
第一大不足:由于我们没办法设置synchronized关键字在获取锁的时候等待时间,所以synchronized可能会导致线程为了加锁而无限期地处于阻塞状态。第二大不足:使用synchronized关键字等同于使用了互斥锁,即其他线程都无法获得锁对象的访问权。这种策略对于读多写少的应用而言是很不利的,因为即使多个读者看似可以并发运行,但他们实际上还[...]

撰写于    浏览:349 次  分类: 一针见血20点
少即是多,20点,已经不少了。不在于量,而在于质。本系列只收录20点一针见血的观点和认识。知识非我创造,但是观点是我思考的。