精华内容
下载资源
问答
  • ArcGIS可见性分析之提取天际线与可见性分析视频教程
  • ArcGIS可见性分析教学PPT
  • Mysql InnoDB多版本可见性分析,由何登成编写,非常经典值得看看
  • 综合考虑实际空间环境中的各个影响因素,提出了编队卫星在轨运行时做可见性分析的方法,得出了对在轨目标进行天基光学观测的可见性分析结果,为编队星座技术应用于天基光学观测提供了技术支撑。
  • [ STK ](三)STK 卫星间可见性分析

    千次阅读 2020-06-18 11:33:36
    STK 仿真模拟,使用 Access 根据,实现卫星可见性分析

    一、创建好的星座如下图

    • 3D 视图
      在这里插入图片描述
    • 2D 视图在这里插入图片描述

    二、创建好星座之后,点击 Analysis - - > Access

    在这里插入图片描述

    三、点击Select Object,选择目标卫星

    在这里插入图片描述
    在这里插入图片描述

    四、选择要分析可见性的卫星

    • 按住Shift键,选择除目标卫星之外的其他卫星(MEO是种子卫星,不选择)
      在这里插入图片描述
    • 点击computer,进行可见性分析
      在这里插入图片描述

    五、点击computer之后,星座视图有如下变化

    在这里插入图片描述
    在这里插入图片描述

    六、生成可见性分析报告

    • 分别生成文字和图表报告
      在这里插入图片描述
    • 文字报告
      在这里插入图片描述
    • 图表报告
      在这里插入图片描述

    在这里插入图片描述

    展开全文
  • 线程安全之可见性分析一、JVM内存模型二、可见性问题引入1、CUP缓存2、指令重排优化 一、JVM内存模型 jvm内存模型是对java程序访问内存进行读写过程的抽象。分为线程共享和线程私有两大块: 线程共享:所有线程都能...

    一、JVM内存模型

    jvm内存模型是对java程序访问内存进行读写过程的抽象。分为线程共享和线程私有两大块:
    在这里插入图片描述
    线程共享:所有线程都能访问的内存数据,随虚拟机或GC创建或销毁
    线程私有:每个线程都会单独开辟空间,随线程创建和销毁

    二、可见性问题引入

    首先我们看一段代码:

    public class ThreadVisib {
    	private boolean flag = true;
    	public static void main(String[] args) throws InterruptedException {
    		ThreadVisib tvb = new ThreadVisib();
    		new Thread(new Runnable() {
    			int i = 0;
    			@Override
    			public void run() {
    				while (tvb.flag) {
    					i++;
    				}
    				System.out.println("线程结束:" + i);
    			}
    		}).start();
    		Thread.sleep(2000);
    		tvb.flag = false;
    		System.out.println("主线程修改了flag:" + tvb.flag);
    	}
    }
    

    执行结果:
    主线程修改了flag:false
    程序进入死循环,我们看看这段代码做了什么:先启动附线程,循环对i做加法操作,主线程2两秒后将flag熟悉置为false。同样是访问ThreadVisib对象的属性,但主线程对flag的修改附线程并不可见,这里就是线程间的可见性问题了。将flag设为volatile我们再来看下程序运行结果:

    public class ThreadVisib {
    	private volatile boolean flag = true;
    	public static void main(String[] args) throws InterruptedException {
    		ThreadVisib tvb = new ThreadVisib();
    		new Thread(new Runnable() {
    			int i = 0;
    			@Override
    			public void run() {
    				while (tvb.flag) {
    					i++;
    				}
    				System.out.println("线程结束:" + i);
    			}
    		}).start();
    		Thread.sleep(2000);
    		tvb.flag = false;
    		System.out.println("主线程修改了flag:" + tvb.flag);
    	}
    }
    

    输出结果:
    主线程修改了flag:false
    线程结束:1090858917
    volatile 关键字保证了主线程对flag的修改立即被附线程可见。
    造成不可见性原因分析:

    1、CUP缓存

    在这里插入图片描述
    java程序执行到底还是CPU在工作,在工作内存到主内存之间,还存在CPU缓存机制,由此可能导致不同CPU之间缓存不同而导致读到的数据不一致问题。但这种原因不会导致死循环,因为缓存即有有效期,还是能读到主内存中最新的数据的。

    2、指令重排优化

    java语言在编译为class时,编译器会对编译后的指令在不改变程序逻辑的情况下进行重排优化。在单线程下不存在问题,但是多线程访问就会产生矛盾的行为。
    蓝不够了,编不下去了。。。

    展开全文
  • 转载自 深度好文 | Java 可重入锁内存可见性分析一个习以为常的细节之前在做 ReentrantLock 相关的试验,试验本身很简单,和本文相关的简化版如下:(提示:以下代码均可左右滑动)private static ReentrantLock ...

    转载自 深度好文 | Java 可重入锁内存可见性分析

    一个习以为常的细节

    之前在做 ReentrantLock 相关的试验,试验本身很简单,和本文相关的简化版如下:(提示:以下代码均可左右滑动)

    private static ReentrantLock LOCK = new ReentrantLock();
    private static int count = 0;
    ...
    // 多线程 run 如下代码
    
    LOCK.lock();
    try {
       count++;
    } finally {
       LOCK.unlock();
    }
    ...

    就是通过可重入锁的保护并行对共享变量进行自增。

    突然想到一个问题:共享变量 count 没有加 volatile 修饰,那么在并发自增的过程当中是如何保持内存立即可见的呢?上面的代码做自增肯定是没问题的,可见 LOCK 不仅仅保证了独占性,必定还有一种机制保证了内存可见性。

    可能很多人和我一样,对 LOCK 的认知是如此 “理所应当”,以至于从没有去思考为什么。就好像每天太阳都会从东方升起而不觉得这有什么好质疑的。现在既然问到这儿了,那就准备一探究竟。

    几个概念

    Java Memory Model (JMM)

    即 Java 内存模型,直接引用 wiki 定义:

    "The Java memory model describes how threads in the Java programming language interact through memory. Together with the description of single-threaded execution of code, the memory model provides the semantics of the Java programming language."

    JMM 定义了线程和内存之间底层交互的语义和规范,比如多线程对共享变量的写 / 读操作是如何互相影响。

    Memory ordering

    Memory ordering 跟处理器通过总线向内存发起读 (load)写 (store)的操作顺序有关。对于早期的 Intel386 处理器,保证了内存底层读写顺序和代码保持一致,我们称之为 program ordering,即代码中的内存读写顺序就限定了处理器和内存交互的顺序,所见即所得。而现代的处理器为了提升指令执行速度,在保证程序语义正确的前提下,允许编译器对指令进行重排序。也就是说这种指令重排序对于上层代码是感知不到的,我们称之为 processor ordering.

    JMM 允许编译器在指令重排上自由发挥,除非程序员通过 synchronized/volatile/CAS 显式干预这种重排机制,建立起同步机制,保证多线程代码正确运行。

    Happens-before

    对于 volatile 关键字大家都比较熟悉,该关键字确保了被修饰变量的内存可见性。也就是线程 A 修改了 volatile 变量,那么线程 B 随后的读取一定是最新的值。然而对于如下代码有个很容易被忽视的点:

    int a = 0;
    volatile int b = 0;
    ...
    a = 1; // line 1
    b = 2; // line 2

    当线程 A 执行完 line 2 之后,变量 a 的更新值也一同被更新到内存当中,JMM 能保证随后线程 B 读取到 b 后,一定能够看到 a = 1。之所以有这种机制是因为 JMM 定义了 happens-before 原则,直接贴资料:

    • Each action in a thread happens-before every action in that thread that comes later in the program order

    • An unlock on a monitor happens-before every subsequent lock on that same monitor

    • A write to a volatile field happens-before every subsequent read of that same volatile

    • A call to Thread.start() on a thread happens-before any actions in the started thread

    • All actions in a thread happen-before any other thread successfully returns from a Thread.join()on that thread

    其中第 3 条就定义了 volatile 相关的 happens-before 原则,类比下面的同步机制,一图胜千言:

    也就是说 volatile 写操作会把之前的共享变量更新一并发布出去,而不只是 volatile 变量本身。Happens-before 原则会保证 volatile 写之后,针对同一个 volatile 变量读,后面的所有共享变量都是可见的。

    初步释疑

    Happens-before 正是解释文章开头问题的关键,以公平锁为例,我们看看 ReentrantLock 获取锁 & 释放锁的关键代码:

    private volatile int state; // 关键 volatile 变量
    protected final int getState() {
       return state;
    }
    
    // 获取锁
    protected final boolean tryAcquire(int acquires) {
       final Thread current = Thread.currentThread();
       int c = getState(); // 重要!!!读 volatile 变量
       ... // 竞争获取锁逻辑,省略   
    }
    
    // 释放锁
    protected final boolean tryRelease(int releases) {
       boolean free = false;
       ... // 根据状态判断是否成功释放,省略
       setState(c); // 重要!!!写 volatile 变量
       return free;
    }

    简单来说就是对于每一个进入到锁的临界区域的线程,都会做三件事情:

    • 获取锁,读取 volatile 变量;

    • 执行临界区代码,针对本文是对 count 做自增;

    • 写 volatile 变量 (即发布所有写操作),释放锁。

    结合上面 happens-before 概念,那么 count 变量自然就对其它线程做到可见了。

    事情还没有结束

    我们只是利用 volatile 的 happens-before 原则对问题进行了初步的解释,happens-before 本身只是一个 JMM 的约束,然而在底层又是怎么实现的呢?这里又有一个重要的概念:内存屏障(Memory barriers)。

    我们可以把内存屏障理解为 JMM 赖以建立的底层机制,wiki 定义:

    "A memory barrier, also known as a membar, memory fence or fence instruction, is a type of barrier instruction that causes a central processing unit (CPU) or compiler to enforce an ordering constraint on memoryoperations issued before and after the barrier instruction. This typically means that operations issued prior to the barrier are guaranteed to be performed before operations issued after the barrier."

    简而言之就是内存屏障限制死了屏障前后的内存操作顺序,抽象出来有四种内存屏障(因为内存 load/store 最多也就四种组合嘛),具体实现视不同的处理器而不同,我们这里看最常见的 x86 架构的处理器:volatile 的 happens-before 原则其实就是依赖的 StoreLoad 内存屏障,重点关注 LOCK 指令实现,这和 volatile 的底层实现息息相关,查看下面代码片段对应的汇编代码:

    package main.java.happenbefore;
    /**
    * Created by zhoutong on 17/11/18.
    */
    public class MyTest {
       private static long a;
       private static int b;
       private volatile static int c;
       public static void main(String[] args) {
           set();
           setAgain();
       }
    
       public static void set() {
           a = 1;
           b = 1;
           c = 1;
       }
    
       public static void setAgain(){
           if (c == 1) {
               a = 2;
               b = 2;
           }
       }
    }

    利用 hsdis 查看对应汇编片段(只包含关键部分):可以看到在 set() 方法对 a,b,c 赋值后,多出了一行 "lock addl $0x0,(%rsp)",这行代码只是对 stack pointer 加 0,无含义。但通过上文我们得知,x86 架构处理器的 LOCK prefix 指令相当于 StoreLoad 内存屏障。LOCK prefix 的指令会触发处理器做特殊的操作,查看 Intel 64 and IA-32 开发手册的相关资料:

    "Synchronization mechanisms in multiple-processor systems may depend upon a strong memory-ordering model. Here, a program can use a locking instruction such as the XCHG instruction or the LOCK prefix to ensure that a read-modify-write operation on memory is carried out atomically. Locking operations typically operate like I/O operations in that they wait for all previous instructions to complete and for all buffered writes to drain to memory."

    LOCK prefix 会触发 CPU 缓存回写到内存,而后通过 CPU 缓存一致性机制(这又是个很大的话题),使得其它处理器核心能够看到最新的共享变量,实现了共享变量对于所有 CPU 的可见性。

    总结

    针对本文开头提出的内存可见性问题,有着一系列的技术依赖关系才得以实现:count++ 可见性 → volatile 的 happens-before 原则 → volatile 底层 LOCK prefix 实现 → CPU 缓存一致性机制。

    补充一下,针对 ReentrantLock 非公平锁的实现,相比公平锁只是在争夺锁的开始多了一步 CAS 操作,而 CAS 在 x86 多处理器架构中同样对应着 LOCK prefix 指令,因此在内存屏障上有着和 volatile 一样的效果。

    参考资料

    http://gee.cs.oswego.edu/dl/jmm/cookbook.html

    https://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-vol-3a-part-1-manual.html 第 8 章

    https://www.ibm.com/developerworks/library/j-jtp03304/index.html

    https://stackoverflow.com/questions/2972389/why-is-compareandswap-instruction-considered-expensive

    http://ifeve.com/java-memory-model-5/

    https://en.wikipedia.org/wiki/Memory_barrier

    https://en.wikipedia.org/wiki/Javamemorymodel



    展开全文
  • java的内存可见性分析

    2018-09-07 22:09:04
    java多线程之内存可见性 共享变量在线程间的可见性 Synchronized实现可见性 volatile实现可见性  指令重排序  as if -serial语意  volatile使用注意事项 Synchronized和volatile的比较 1.可见性介绍  可见性:...

    java多线程之内存可见性
    共享变量在线程间的可见性
    Synchronized实现可见性
    volatile实现可见性
         指令重排序
         as if -serial语意
         volatile使用注意事项
    Synchronized和volatile的比较

    1.可见性介绍
        可见性:一个线程对共享变量的修改,能够及时的被其他线程看到
        共享变量:如果一个变量在多个线程中存有副本,那么这个变量就是这几个线程的共享变量
        java内存模型(JMM)
        java内存模型(java memory model)描述了java程序中各种变量(线程共享变量)的访问规则,以及在jvm中将变量储存到内存
        和从内存中读取出变量的底层细节。

    2.通过Synchronized和volatile都可以实现可见性
      线程对共享变量的所有操作都必须在自己的工作内存中进行
      所有的变量都储存在主内存中

    3.要实现共享变量的可见性,必须保证二点
      线程修改后的共享变量值能够及时保证从工作内存中刷新到主内存中。
      其他线程能够及时把共享变量的最新值从主内存中刷新到自己的工作内存中去。

    4.可见性的实现方式
    java语言支持的可见性实现方式
    synchronized和volatile
    1.)Synchronized能够实现
    原子性,同步


    JMM关于Synchronized的二条规定:
    1.1 线程解锁前,必须把共享变量的最新值刷新到主内存中去
    1.2 线程加锁时,将清空工作内存中共享变量的值,从而使用共享变量时需要从主内存重新读取最新的值
    (注意:加锁和解锁需要同一把锁)
    线程解锁前对共享变量的修改在下次加锁时对其他线程可见
    线程执行互斥锁代码的过程
    1,获得互斥锁
    2,清空工作内存
    3,从主内存中拷贝最新副本的变量到工作内存中
    4,执行代码
    5,将更改后共享变量的值刷新到主内存中
    6,释放互斥锁

    重排序:
    代码书写的顺序与实际执行的顺序不同,指令重排序是编译器或处理器为了
    提高程序性能做的优化
    1.编译器优化的重排序(编译器优化)
    2.指令级并行重排序(处理器优化)
    3.内存系统的重排序(处理器优化)

    as-if-serial
    as-if-serial:无论如何重排序,程序执行的效果应该与代码的顺序执行的结果一致
    (java编辑器,运行时和处理器都会保证java在单线程下遵守as-if-serial语句)

    导致共享变量在线程间不可见的原因
    1. 线程的交叉执行                                                                                       原子性
    2. 重排序结合线程交叉执行                                                                         原子性
    3. 共享变量更新后的值没有在工作内存与主内存之间及时更新                    可见性

    展开全文
  • 3D分析之可见性分析工具

    万次阅读 2014-02-11 11:41:15
    ArcGIS 通过分析功能面的视域来确定不同区域中的可见性。 视域的计算:如果仅有一个观测点,则为可从观测点看到的单元赋值 1,为无法从观测点看到的所有单元赋值 0。 1. Construct Sight Lines(构造视线) ...
  • JAVA内存可见性分析

    2020-02-24 18:27:10
    关于内存不可见性的验证网上的例子很多,比如 https://blog.csdn.net/weixin_33656548/article/details/88846777 ; 上文JDK版本jdk1.8.0_201,本人是 jdk1.8.0_202 ; public class VolatileTest { public...
  • java可重入锁-ReentrantLock实现细节 ReentrantLock支持两种获取锁的方式,一种是公平...这时候,村民A来打水(A线程请求锁),占了打水权,把state+1,如下所示: 线程A取得了锁,把 state原子+1,这时候state被...
  • java多线程之内存可见性主要讲解以后几点: 共享变量在线程间可见性。... 概念分析可见性:一个线程对共享变量值的修改,能够及时地被其他线程看到。 共享变量:如果一个变量在多个线程的内存中都存在副本,那么这个
  • 直接上代码 public class Test { private static volatile boolean flag = true; public static void main(String[] args) { new Thread(() -> { while (flag) { } System.out.println("==========...
  • 该插件旨在用于更复杂的建模,例如可见地平线以下的深度或成组的点之间的可见性网络。 对于形成一组固定点的多个视域计算,该功能特别有效。 安装: 该插件可以从官方QGIS存储库中以其他方式安装(在QGIS中,转到...
  • java之线程可见性分析

    2020-03-24 09:31:53
    } } 问题分析 使用javap分析底层字节码 案例1 public class org.gallant.jitwatch.VisibilityWithoutVolatile extends java.lang.Thread ... { public org.gallant.jitwatch.VisibilityWithoutVolatile(); ...
  • 本文提出了一种新的基于中轴变换(MAT)的点云可见性分析方法。这种基于MAT的方法具有几个优点,该方法避免了点云曲面重建,适用于输入点云中缺少曲面的情况。对于网格生成的点云、AHN3点云和稠密图像匹配生成的点云...
  • 卫星仿真工具包能够准确计算出特定目标与其他相关对象的空间关系,以仿真时间或真实时间精确显示并分析陆、海、空、天目标,也可实现卫星以及其他载荷的覆盖分析。其重要模块Matlab Interface可建立与Matlab的连接。...
  • 从上述可知,在JVM运行数据区中,工作内存与主内存是通过JMM模型规范来完成彼此之间的数据交互,因此可以通过JMM定义的内存语义规范来提供数据变量的可见性 基于缓存问题解决方案 JMM规范规定使用针对的技术手段时...
  • 注:java虚拟机可能使用寄存器来处理volatile变量,只要符合volatile可见性的语义!这是一个必须遵守的原则,而不是实际执行的原则。 另外我们可以使用synchronized 关键字来代替volatile,原理是在进入同步边界,...
  • 可见性:一个线程对共享变量值的修改,能够及时地被其他线程看到。Java内存模型(JMM)描述了Java程序中各种变量(线程共享变量)的访问规则,以及在JVM中将变量存储到内存中和从内存中读取出变量这样的底层细节。多...
  • 这一差异考虑了这一事实,一个图像内容的出现将要降低在其空间或时间,空间频率或方向附近出现的另一个内容的可见性。   Normalization 过程就是打算将误差转换到 Just noticeable difference 单位。   ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,980
精华内容 1,192
关键字:

可见性分析