整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

Fences4使用教程

Fences4使用教程

ences4使用教程

1.我们完成Fences4软件安装之后,打开软件系统便会自动弹出相应的窗口,接着我们选择第一个安装文件类型进行自动整理,便会出现如下界面;

2.然后我们来讲讲软件最核心的功能--画区,该功能有两种操作方式,一种是我们拖动鼠标右键创建合适的软件程序分区,接着把相应的文件扔进去就好了;

3.另一种专门针对桌面文件夹所打造的,我们可以直接在右键菜单中选择「在桌面上显示此文件夹」,然后快速创建分区;

4.这样一来,我们就无需花费时间在从资源管理器中查看文件夹内容,我们可以直接点击Fences分区,一层层进入到文件夹内容中去,省去了不少繁琐的操作步骤;

5.全局置顶是针对最新版本所推出的功能,我们可以利用快捷键「Win+空格」和「Win+Ctrl+空格」在桌面任意界面调出分区面板;

6.此外,还为桌面还配有隐藏的功能,你可以双击桌面直接隐藏,需要使用时双击桌面重新显示;

7.也可以在设置里启用不适用桌面时自动隐藏图标的功能,眼不见心不烦,切回桌面或双击时再显示图标;

8.除了上面介绍的这些,Fences 的强大还体现在——支持桌面自动快照备份,以防桌面出岔子;

9.桌面上、分区内,所有文件可按打开次数排序;

10.只要你合理搭配 Fences 的功能,你完全可以实现这样的效果。

教程来源于:https://www.81857.net/soft/63210.html


本文讨论什么是内存屏障(其实它是软件协调硬件工作的一个指令),以及如何应用volatile(在JAVA世界中内存屏障的语义是由volatile关键字来实现的),最后介绍在disruptor中如何应用的。

什么是内存屏障



它是一个CPU指令。我们在讨论CPU级别的东西,以便获得我们想要的性能(Martin著名的Mechanical Sympathy理论https://mechanical-sympathy.blogspot.com/2011/07/memory-barriersfences.html)。


基本上,它是这样一条指令: a)确保一些特定操作执行的顺序; b)影响一些数据的可见性(可能是某些指令执行后的结果)。

编译器和CPU可以在保证输出结果一样的情况下对指令重排序,使性能得到优化。插入一个内存屏障,相当于告诉CPU和编译器先于这个命令的必须先执行,后于这个命令的必须后执行。

内存屏障另一个作用是强制更新一次不同CPU的缓存。例如,一个写屏障会把这个屏障前写入的数据刷新到缓存,这样任何试图读取该数据的线程将得到最新值,而不用考虑到底是被哪个cpu核心或者哪颗CPU执行的。

和JAVA什么关系



JAVA里有个关键字叫volatile,在JAVA世界中内存屏障的语义是由volatile关键字来实现的。JAVA 语言是支持多线程的,为了解决多线程的安全问题 JAVA 语言引进了 synchronized 同步块和 volatile关键字机制。

volatile是轻量级的synchronized,它在多处理器开发中保证了共享变量的“可见性”。可见性的意思是当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值。

为什么要使用volatile



解决多线程下数据安全共享的问题;volatile变量修饰符如果使用恰当的话,它比synchronized的使用和执行成本会更低,因为它不会引起线程上下文的切换和调度。


volatile的实现原理



那么Volatile是如何来保证可见性的呢?在x86处理器下通过工具获取JIT编译器生成的汇编指令来看看对Volatile进行写操作CPU会做什么事情。

Java代码:

instance=new Singleton();//instance是volatile变量

汇编代码:

0x01a3de1d: movb >0x01a3de1d: movb $0x0,0x1104800(%esi);0x01a3de24: lock addl >addl $0x0,(%esp);<>


有volatile变量修饰的共享变量进行写操作的时候会多第二行汇编代码,通过查IA-32架构软件开发者手册可知,lock前缀的指令在多核处理器下会引发了两件事情。

  • 将当前处理器缓存行的数据会写回到系统内存。
  • 这个写回内存的操作会引起在其他CPU里缓存了该内存地址的数据无效。


处理器为了提高处理速度,不直接和内存进行通讯,而是先将系统内存的数据读到内部缓存(L1,L2或其他)后再进行操作,但操作完之后不知道何时会写到内存,如果对声明了Volatile变量进行写操作,JVM就会向处理器发送一条Lock前缀的指令,将这个变量所在缓存行的数据写回到系统内存。但是就算写回到内存,如果其他处理器缓存的值还是旧的,再执行计算操作就会有问题,所以在多处理器下,为了保证各个处理器的缓存是一致的,就会实现缓存一致性协议,每个处理器通过嗅探在总线上传播的数据来检查自己缓存的值是不是过期了,当处理器发现自己缓存行对应的内存地址被修改,就会将当前处理器的缓存行设置成无效状态,当处理器要对这个数据进行修改操作的时候,会强制重新从系统内存里把数据读到处理器缓存里。


小贴士:

这两件事情在IA-32软件开发者架构手册的第三册的多处理器管理章节(第八章)中有详细阐述。

Lock前缀指令会引起处理器缓存回写到内存。Lock前缀指令导致在执行指令期间,声言处理器的 LOCK# 信号。在多处理器环境中,LOCK# 信号确保在声言该信号期间,处理器可以独占使用任何共享内存。(因为它会锁住总线,导致其他CPU不能访问总线,不能访问总线就意味着不能访问系统内存),但是在最近的处理器里,LOCK#信号一般不锁总线,而是锁缓存,毕竟锁总线开销比较大。在8.1.4章节有详细说明锁定操作对处理器缓存的影响,对于Intel486和Pentium处理器,在锁操作时,总是在总线上声言LOCK#信号。

但在P6和最近的处理器中,如果访问的内存区域已经缓存在处理器内部,则不会声言LOCK#信号。相反地,它会锁定这块内存区域的缓存并回写到内存,并使用缓存一致性机制来确保修改的原子性,此操作被称为“缓存锁定”,缓存一致性机制会阻止同时修改被两个以上处理器缓存的内存区域数据。

一个处理器的缓存回写到内存会导致其他处理器的缓存无效IA-32处理器和Intel 64处理器使用MESI(修改,独占,共享,无效)控制协议去维护内部缓存和其他处理器缓存的一致性。在多核处理器系统中进行操作的时候,IA-32 和Intel 64处理器能嗅探其他处理器访问系统内存和它们的内部缓存。它们使用嗅探技术保证它的内部缓存,系统内存和其他处理器的缓存的数据在总线上保持一致。例如在Pentium和P6 family处理器中,如果通过嗅探一个处理器来检测其他处理器打算写内存地址,而这个地址当前处理共享状态,那么正在嗅探的处理器将无效它的缓存行,在下次访问相同内存地址时,强制执行缓存行填充。


volatile使用误区




volatile很容易被误用,用来进行原子性操作。

与使用 synchronized相比,声明一个 volatile 字段的区别在于没有涉及到锁操作。但特别的是对 volatile 字段进行“ ++ ”这样的读写操作不会被当做原子操作执行。同时测试了字符串拼接的操作,也是不安全的。下文中有代码已经证实 volatile 关键字修饰的变量在多线程写的情况下不安全。


public class Counter {
//    public volatile static int count=0;


    public volatilestatic StringBuilder count=new StringBuilder("aa");


    public static void inc(String a){
        //这里延迟1毫秒,使得结果明显
        try {
            Thread.sleep(1);
        } catch (InterruptedExceptione) {


        }
            count .append(a+"-");


    }


    public static void main(String[]args) {
        //同时启动1000个线程,去进行i++计算,看看实际结果
        for (int i=1; i <=1000; i++) {
            int finalI=i;
            new Thread(new Runnable(){
                @Override
                publicvoid run() {
                   Counter.inc(String.valueOf(finalI));
                }
            }).start();
        }
        //这里每次运行的值都有可能不同,可能为1000
        System.out.println("运行结果:Counter.count=" + Counter.count);
    }
}



运行结果还是没有我们期望的 aa-XX-1000,下面我们分析一下原因。


在 java 垃圾回收整理一文中,描述了 jvm 运行时刻内存的分配。其中有一个内存区域是 jvm 虚拟机栈,每一个线程运行时都有一个线程栈,线程栈保存了线程运行时候变量值信息。当线程访问某一个对象时候值的时候,首先通过对象的引用找到对应在堆内存的变量的值,然后把堆内存变量的具体值 load 到线程本地内存中,建立一个变量副本,之后线程就不再和对象在堆内存变量值有任何关系,变量的具体值 load 到线程本地内存中,建立一个变量副本,之后线程就不再和对象在堆内存变量值有任何关系,而是直接修改副本变量的值,在修改完之后的某一个时刻(线程退出之前),自动把线程变量副本的值回写到对象在堆中变量。这样在堆中的对象的值就产生变化了。下面一幅图描述这些交互。



read and load 从主存复制变量到当前工作内存

use and assign 执行代码,改变共享变量值

store and write 用工作内存数据刷新主存相关内容, 其中 use and assign 可以多次出现,但是这一些操作并不是原子性,也就是在 read load 之后,如果主内存 count 变量发生修改之后,线程工作内存中的值由于已经加载,不会产生对应的变化,所以计算出来的结果会和预期不一样。

对于 volatile 修饰的变量, jvm 虚拟机只是保证从主内存加载到线程工作内存的值是最新的。

例如假如线程 1 ,线程 2 在进行 read,load 操作中,发现主内存中 count 的值都是 5 ,那么都会加载这个最新的值

在线程 1 堆 count 进行修改之后,会 write 到主内存中,主内存中的 count 变量就会变为 6

线程 2 由于已经进行 read,load 操作,在进行运算之后,也会更新主内存 count的变量值为 6

导致两个线程及时用 volatile 关键字修改之后,还是会存在并发的情况。


暂且不管在多线程下对 volatile 修饰的变量进行修改是否安全的,但是在多线程下对 volatile 修饰的变量进行读操作是安全的,后一点是无可非议的。所以有了以下的结论: volatile 的适用场景当只有一个线程可以修改字段的值,其它线程可以随时读取,那么把字段声明为 volatile 是合理的。


对性能的影响



内存屏障作为另一个CPU级的指令,没有锁那样大的开销,可以看之前文章

Disruptor为什么会如此快 - (一)锁的成本的实验结果。内核并没有在多个线程间干涉和调度。

Disruptor如何使用内存屏障



下图是Disruptor的AbsttactSequencer源码截图。



把Sequence定义为volatile 类型,供多线程共享。从截图可以看出gatingSequences在对象实例化时进行了初始化(写操作),多处进行读操作。这个与先前得出的结论颇为相似:volatile 的适用场景当只有一个线程可以修改字段的值,其它线程可以随时读取,那么把字段声明为 volatile 是合理的。


小结



1、内存屏障是CPU指令,它允许你对数据什么时候对其他进程可见作出假设。在Java世界里,使用volatile关键字来实现内存屏障。使用volatile意味着不用被迫选择加锁,并且还能获得性能的提升。

2、volatile的适用场景:当只有一个线程可以修改字段的值,其它线程可以随时读取,那么把字段声明为 volatile 是合理的。


如果此文能帮小伙伴答疑解惑,请关注「架构那些事儿」

你的关注就是我的动力!

多人都喜欢用外国软件,其实有很多国产软件也非常好用,今天给大家推荐6个优质的国产软件,款款精挑细选,让你的Windows电脑更好用。

01.Fences(桌面瞬间整洁)

这是一款专注于桌面整理的软件,把桌面栅栏式划分为多个区块进行管理,按照文件的类型进行自动归类,效果立竿见影。用了它之后,我的桌面随时都能保持整洁干净。

02.Quicker(快速启动工具)

这是一个快速启动工具,主要功能就是能够让你快速启动其他应用,涵盖范围包括电脑中所有的软件以及网页,而且启动什么你都是能自定义设置的,非常方便。

03.分区助手(电脑磁盘分区)

电脑C盘难免会有空间不足的情况,如果不及时清理释放空间,就会严重拖累系统运行速度。我们可以考虑用分区助手,来重新调整各个盘符的内存容量,操作简单,不会损坏原有数据,非常好用。

04.迅捷压缩(文件批量压缩)

这是一个文件压缩神器,支持图片、视频、PDF、Word、PPT压缩,做到极致无损压缩效果,尤其是工作中需要处理很多文件,用它可以批量压缩,高效办公。

05.字由(电脑字体管理)

这是一款字体应用类软件,可在线上实现字体管理、预览、备份与范例展示,也可以把字体下载下来,用于设计logo、海报等,这里的字体都是支持商用的哦。

06.HBuilder(网页前端开发)

这个工具就比较高端了,主要是用于网页前端开发的,也是目前市面上速度最快的HTML开发工具,强大的代码助手能帮你快速完成开发,同时还支持最全的语法库和浏览器兼容性数据,妥妥的一个神器!

最美尾巴:

以上就是我今天分享的内容,如果大家觉得有用,记得点赞告诉我,我会继续分享更多优质的内容。

上面这6个优质的国产软件,款款精挑细选,让你的Windows电脑更好用。