volatile

Unsafe类

余生颓废 提交于 2020-01-06 14:47:36
一、Unsafe类仅能被BootstrapClassLoader加载的类实例化,用户建的类默认都是ApplicationClassLoader加载的,实例化Unsafe时会报错。可以用反射实例化(方式一)。补充:加启动参数指定当前类由BootstrapClassLoader加载(方式二) private Unsafe() {//构造方法私有化 同单例模式 防止new } @CallerSensitive public static Unsafe getUnsafe() { Class var0 = Reflection.getCallerClass(); if (!VM.isSystemDomainLoader(var0.getClassLoader())) {//判断是否BootstrapClassLoader加载的类执行实例化的 throw new SecurityException("Unsafe"); } else { return theUnsafe; } } 二、反射实现实例化 public class UnsafeTest2 { static final Unsafe unsafe; static final long stateOffset; private volatile long state = 0; static { try { Field field =

Using the same variables in two threads, but I don't know why they won't update in Java

一曲冷凌霜 提交于 2020-01-06 01:27:06
问题 I would like to start off by saying that I know there are similar questions to this. I did some searching, and I DID find some information. Unfortunately, the solutions did not help me. I do not know why. This is why I ask this question. I have two Threads I am working with in Java. I have four classes that are related to this. The first class is the class with the 'main' method in it. It sets up and starts all the Threads. Here is how I start and declare the Threads: Thread thread1 = new

如何停止JAVA线程

我的未来我决定 提交于 2020-01-06 00:35:28
本文以转移至本人的个人博客,请多多关注! 本文以转移至本人的个人博客,请多多关注! 本文以转移至本人的个人博客,请多多关注! http://blog.csdn.net/anhuidelinger/article/details/11746365 终止线程的三种方法 有三种方法可以使终止线程。 1. 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。 2. 使用stop方法强行终止线程(这个方法不推荐使用,因为stop和suspend、resume一样,也可能发生不可预料的结果)。 3. 使用interrupt方法中断线程。 1. 使用退出标志终止线程 当run方法执行完后,线程就会退出。但有时run方法是永远不会结束的。如在服务端程序中使用线程进行监听客户端请求,或是其他的需要循环处理的任务。 在这种情况下,一般是将这些任务放在一个循环中,如while循环。如果想让循环永远运行下去,可以使用while(true){……}来处理。但要想使 while循环在某一特定条件下退出,最直接的方法就是设一个boolean类型的标志,并通过设置这个标志为true或false来控制while循环 是否退出。下面给出了一个利用退出标志终止线程的例子。 package chapter2; public class ThreadFlag extends Thread { public

Java并发:volatile内存可见性和指令重排

纵然是瞬间 提交于 2020-01-06 00:32:44
volatile两大作用 1、保证内存可见性 2、防止指令重排 此外需注意volatile 并不保证操作的原子性。 (一)内存可见性 1 概念 JVM内存模型:主内存和线程独立的工作内存 Java内存模型规定,对于多个线程共享的变量,存储在主内存当中,每个线程都有自己独立的工作内存(比如CPU的寄存器),线程只能访问自己的工作内存,不可以访问其它线程的工作内存。 工作内存中保存了主内存共享变量的 副本 ,线程要操作这些共享变量,只能通过操作工作内存中的副本来实现,操作完毕之后再同步回到主内存当中。 如何保证多个线程操作主内存的数据完整性是一个难题,Java内存模型也规定了工作内存与主内存之间交互的协议,定义了8种原子操作: (1) lock:将主内存中的变量锁定,为一个线程所独占 (2) unclock:将lock加的锁定解除,此时其它的线程可以有机会访问此变量 (3) read:将主内存中的变量值读到工作内存当中 (4) load:将read读取的值保存到工作内存中的变量副本中。 (5) use:将值传递给线程的代码执行引擎 (6) assign:将执行引擎处理返回的值重新赋值给变量副本 (7) store:将变量副本的值存储到主内存中。 (8) write:将store存储的值写入到主内存的共享变量当中。 通过上面Java内存模型的概述,我们会注意到这么一个问题

volatile VS synchronized

可紊 提交于 2020-01-06 00:32:26
Get it from: http://space.itpub.net/111631/viewspace-610344 volatile关键字有什么用?   恐怕比较一下volatile和synchronized的不同是最容易解释清楚的。volatile是变量修饰符,而synchronized则作用于一段 代码 或方法;看如下三句get代码: int i1; int geti1() {return i1;} volatile int i2; int geti2() {return i2;} int i3; synchronized int geti3() {return i3;}   geti1()得到存储在当前线程中i1的数值。多个线程有多个i1变量拷贝,而且这些i1之间可以互不相同。换句话说,另一个线程可能已经改变了它线程内的i1值,而这个值可以和当前线程中的i1值不相同。事实上,Java有个思想叫“主”内存区域,这里存放了变量目前的“准确值”。每个线程可以有它自己的变量拷贝,而这个变量拷贝值可以和“主”内存区域里存放的不同。因此实际上存在一种可能:“主”内存区域里的i1值是1,线程1里的i1值是2,线程2里的i1值是3——这在线程1和线程2都改变了它们各自的i1值,而且这个改变还没来得及传递给“主”内存区域或其他线程时就会发生。   而geti2()得到的是“主

c#中volatile关键字的作用

試著忘記壹切 提交于 2020-01-06 00:31:54
转载自: http://hi.baidu.com/jy02180723/blog/item/63dc2563564eed630d33fa20.html 恐怕比较一下volatile和synchronized的不同是最容易解释清楚的。volatile是变量修饰符,而synchronized则作用于一段代码或方法;看如下三句get代码: int i1 ; int geti1 () { return i1 ; } volatile int i2 ; int geti2 () { return i2 ; } int i3 ; synchronized int geti3 () { return i3 ; }   geti1()得到存储在当前线程中i1的数值。多个线程有多个i1变量拷贝,而且这些i1之间可以互不相同。换句话说,另一个线程可能已经改变了它线程内的i1值,而这个值可以和当前线程中的i1值不相同。事实上,Java有个思想叫“主”内存区域,这里存放了变量目前的“准确值”。每个线程可以有它自己的变量拷贝,而这个变量拷贝值可以和“主”内存区域里存放的不同。因此实际上存在一种可能:“主”内存区域里的i1值是1,线程1里的i1值是2,线程2里的i1值是3——这在线程1和线程2都改变了它们各自的i1值,而且这个改变还没来得及传递给“主”内存区域或其他线程时就会发生。   而geti2(

c#中volatile关键字的作用

谁说我不能喝 提交于 2020-01-06 00:31:35
恐怕比较一下volatile和synchronized的不同是最容易解释清楚的。volatile是变量修饰符,而synchronized则作用于一段代码或方法;看如下三句get代码: int i1 ; int geti1 () { return i1 ; } volatile int i2 ; int geti2 () { return i2 ; } int i3 ; synchronized int geti3 () { return i3 ; }   geti1()得到存储在当前线程中i1的数值。多个线程有多个i1变量拷贝,而且这些i1之间可以互不相同。换句话说,另一个线程可能已经改变了它线程内的i1值,而这个值可以和当前线程中的i1值不相同。事实上,Java有个思想叫“主”内存区域,这里存放了变量目前的“准确值”。每个线程可以有它自己的变量拷贝,而这个变量拷贝值可以和“主”内存区域里存放的不同。因此实际上存在一种可能:“主”内存区域里的i1值是1,线程1里的i1值是2,线程2里的i1值是3——这在线程1和线程2都改变了它们各自的i1值,而且这个改变还没来得及传递给“主”内存区域或其他线程时就会发生。   而geti2()得到的是“主”内存区域的i2数值。用volatile修饰后的变量不允许有不同于“主”内存区域的变量拷贝。换句话说

c#中volatile关键字的作用

纵然是瞬间 提交于 2020-01-06 00:31:18
恐怕比较一下volatile和synchronized的不同是最容易解释清楚的。volatile是变量修饰符,而synchronized则作用于一段代码或方法;看如下三句get代码: int i1 ; int geti1 () { return i1 ; } volatile int i2 ; int geti2 () { return i2 ; } int i3 ; synchronized int geti3 () { return i3 ; }   geti1()得到存储在当前线程中i1的数值。多个线程有多个i1变量拷贝,而且这些i1之间可以互不相同。换句话说,另一个线程可能已经改变了它线程内的i1值,而这个值可以和当前线程中的i1值不相同。事实上,Java有个思想叫“主”内存区域,这里存放了变量目前的“准确值”。每个线程可以有它自己的变量拷贝,而这个变量拷贝值可以和“主”内存区域里存放的不同。因此实际上存在一种可能:“主”内存区域里的i1值是1,线程1里的i1值是2,线程2里的i1值是3——这在线程1和线程2都改变了它们各自的i1值,而且这个改变还没来得及传递给“主”内存区域或其他线程时就会发生。   而geti2()得到的是“主”内存区域的i2数值。用volatile修饰后的变量不允许有不同于“主”内存区域的变量拷贝。换句话说

AQS深入理解与实战----基于JDK1.8

独自空忆成欢 提交于 2020-01-05 18:50:52
要介绍AQS,首先要介绍“同步器”的概念。 同步器 是一种抽象数据类型,在该类型的内部,维护了以下内容: 1.一个状态变量,该变量的不同取值可以表征不同的同步状态语义(例如表示一个锁已经被线程持有了还是没有任何线程持有); 2.能够更新和检查该状态变量值的操作(方法)集合; 3.至少有一个方法——当同步状态的值需要时可调用该方法阻塞来修改该状态的线程;或当其他的线程修改了同步状态值,可允许调用该方法唤醒其他阻塞线程 简单说,同步器中包含一个 可表征同步状态的变量 , 可操作该变量的方法集 ,以及 可阻塞或唤醒其他来修改该状态的线程的方法集 。 互斥锁,读写锁,信号量,屏障,事件指示器等等都是同步器。 AQS,全称是AbstractQueuedSynchronizer,中文译为 抽象队列式同步器 。这个抽象类对于JUC并发包非常重要,JUC包中的ReentrantLock,,Semaphore,ReentrantReadWriteLock,CountDownLatch等等几乎所有的类都是基于AQS实现的。 “抽象”是说该类是一个 抽象类, “队列式同步器”是说AQS使用 队列来 管理多个抢占资源的线程 。AQS在其内部实现了上面所说的同步器的三要素,而且它会把抢占资源失败的线程放入自己内部的一个队列当中维护起来,在这个队列内部的线程会排队等待获取线程。

汇编语言---GCC内联汇编

我怕爱的太早我们不能终老 提交于 2020-01-05 09:57:48
GCC支持在C/C++代码中嵌入汇编代码,这些代码被称作是"GCC Inline ASM"(GCC内联汇编); 一、基本内联汇编 GCC中基本的内联汇编非常易懂, 格式如下 : __asm__ [__volatile__] ("instruction list"); 其中, 1.__asm__ : 它是GCC定义的关键字 asm 的宏定义(#define __asm__ asm),它用来声明一个内联汇编表达式,所以,任何一个内联汇编表达式都以它开头,它是必不可少的;如果要编写符合ANSI C标准的代码(即:与ANSI C兼容),那就要使用__asm__; 2.__volatile__ : 它是GCC关键字 volatile 的宏定义;这个选项是可选的;它向GCC声明"不要动我所写的instruction list,我需要原封不动地保留每一条指令";如果不使用__volatile__,则当你使用了优化选项-O进行优化编译时,GCC将会根据自己的判断来决定是否将这个内联汇编表达式中的指令优化掉;如果要编写符合ANSI C标准的代码(即:与ANSI C兼容),那就要使用__volatile__; 3.instruction list : 它是汇编指令列表;它可以是空列表,比如:__asm__ __volatile__("");或__asm__("");都是合法的内联汇编表达式