精华内容
下载资源
问答
  • violate,synchronized

    2019-09-29 00:40:30
    violate 修饰符  1,可以防止编译器的优化,因为寄存器与内存的速度差异。往往会导致在多线程内容读取同一变量时,读取的是副本,而非真正的最新值是  所以violate用来保证取值不在...synchronized修饰符:  ...

    violate 修饰符

        1,可以防止编译器的优化,因为寄存器与内存的速度差异。往往会导致在多线程内容读取同一变量时,读取的是副本,而非真正的最新值是

        所以violate用来保证取值不在缓存中读取,而是从真正内存中读取。

        2,原子执行,它修饰的变量的操作不会产生线程不同步的情况,如i++之类的,不加会有不同步的问题。

    synchronized修饰符:

        1,static synchronized 加的锁 锁的是Class,synchronized锁的是对象,会产生并发,造成错误。

          2,synchronized在单例模式(懒汉式)的应用,在下面例子中,因为第二种没有添加singleton为空的判断,所以都会进入

          synchronized(Singleton.class){}之中。从而造成大数据的阻塞。

         a),public static Sigleton getInstance(){

            if(singleton==null)

            {

              synchronized(Singleton.class){

                  .....

              }

            }

         }

          b),public static Sigleton getInstance(){

              synchronized(Singleton.class){

                  .....

              }

         }

            

    转载于:https://www.cnblogs.com/mjaioy/p/3645407.html

    展开全文
  • 前言: 线程安全:提到线程安全,可能大家的第一反应是要确保接口对共享变量的操作要具体原子性。实际上,在多线程编程中我们...可见性:Violate|synchronized 可保证; 有序性:Violate 可部分保证(禁止指令重...

    前言:

    线程安全:提到线程安全,可能大家的第一反应是要确保接口对共享变量的操作要具体原子性。实际上,在多线程编程中我们需要同时关注可见性、顺序性和原子性问题。

    原子性:Atomic|synchronized 可保证;Atomic实现CAS(乐观锁),synchronized为悲观锁;

    可见性:Violate|synchronized 可保证;

    有序性:Violate 可部分保证(禁止指令重排序),synchronized 可保证。

    结论:synchronized同步代码块可保证线程安全(原子性+可见性+有序性)。

     

    Java内存模型

    想要理解volatile为什么能确保可见性,就要先理解Java中的内存模型是什么样的。

    è¿éåå¾çæè¿°

    Java内存模型规定了所有的变量都存储在主内存中。每条线程中还有自己的工作内存,线程的工作内存中保存了被该线程所使用到的变量(这些变量是从主内存中拷贝而来)。线程对变量的所有操作(读取,赋值)都必须在工作内存中进行。不同线程之间也无法直接访问对方工作内存中的变量,线程间变量值的传递均需要通过主内存来完成。

    基于此种内存模型,便产生了多线程编程中的数据“脏读”等问题。

    举个简单的例子:在java中,执行下面这个语句:

    i  = 10;
    i++;
    i++;
    执行线程必须先在自己的工作线程中对变量i所在的缓存行进行赋值操作,然后再写入主存当中。而不是直接将数值10写入主存当中。

    比如同时有2个线程执行这段代码,假如初始时i的值为10,那么我们希望两个线程执行完之后i的值变为12。但是事实会是这样吗?

    可能存在下面一种情况:初始时,两个线程分别读取i的值存入各自所在的工作内存当中,然后线程1进行加1操作,然后把i的最新值11写入到内存。此时线程2的工作内存当中i的值还是10,进行加1操作之后,i的值为11,然后线程2把i的值写入内存。

    最终结果i的值是11,而不是12。这就是著名的缓存一致性问题。通常称这种被多个线程访问的变量为共享变量。

    那么如何确保共享变量在多线程访问时能够正确输出结果呢?在解决这个问题之前,我们要先了解并发编程的三大概念:原子性,有序性,可见性。

     

    何谓Atomic?

    Atomic一词跟原子有点关系,后者曾被人认为是最小物质的单位。计算机中的Atomic是指不能分割成若干部分的意思。如果一段代码被认为是Atomic,则表示这段代码在执行过程中,是不能被中断的。通常来说,原子指令由硬件提供,供软件来实现原子方法(某个线程进入该方法后,就不会被中断,直到其执行完成)

     

    在x86 平台上,CPU提供了在指令执行期间对总线加锁的手段。CPU芯片上有一条引线#HLOCK pin,如果汇编语言的程序中在一条指令前面加上前缀"LOCK",经过汇编以后的机器代码就使CPU在执行这条指令的时候把#HLOCK pin的电位拉低,持续到这条指令结束时放开,从而把总线锁住,这样同一总线上别的CPU就暂时不能通过总线访问内存了,保证了这条指令在多处理器环境中的原子性。

     

    JDK1.5的原子包:java.util.concurrent.atomic

    这个包里面提供了一组原子类。其基本的特性就是在多线程环境下,当有多个线程同时执行这些类的实例包含的方法时,具有排他性,即当某个线程进入方法,执行其中的指令时,不会被其他线程打断,而别的线程就像自旋锁一样,一直等到该方法执行完成,才由JVM从等待队列中选择一个另一个线程进入,这只是一种逻辑上的理解。实际上是借助硬件的相关指令来实现的,不会阻塞线程(或者说只是在硬件级别上阻塞了)。其中的类可以分成4组

    • AtomicBoolean,AtomicInteger,AtomicLong,AtomicReference
    • AtomicIntegerArray,AtomicLongArray
    • AtomicLongFieldUpdater,AtomicIntegerFieldUpdater,AtomicReferenceFieldUpdater
    • AtomicMarkableReference,AtomicStampedReference,AtomicReferenceArray

    Atomic类的作用

    • 使得让对单一数据的操作,实现了原子化
    • 使用Atomic类构建复杂的,无需阻塞的代码
      • 访问对2个或2个以上的atomic变量(或者对单个atomic变量进行2次或2次以上的操作)通常认为是需要同步的,以达到让这些操作能被作为一个原子单元。

    AtomicBoolean , AtomicInteger, AtomicLong, AtomicReference

    这四种基本类型用来处理布尔,整数,长整数,对象四种数据。

    • 构造函数(两个构造函数)
      • 默认的构造函数:初始化的数据分别是false,0,0,null
      • 带参构造函数:参数为初始化的数据
    • set( )和get( )方法:可以原子地设定和获取atomic的数据。类似于volatile,保证数据会在主存中设置或读取
    • getAndSet( )方法
      • 原子的将变量设定为新数据,同时返回先前的旧数据
      • 其本质是get( )操作,然后做set( )操作。尽管这2个操作都是atomic,但是他们合并在一起的时候,就不是atomic。在Java的源程序的级别上,如果不依赖synchronized的机制来完成这个工作,是不可能的。只有依靠native方法才可以。
    • compareAndSet( ) 和weakCompareAndSet( )方法
      • 这两个方法都是conditional modifier方法。这2个方法接受2个参数,一个是期望数据(expected),一个是新数据(new);如果atomic里面的数据和期望数据一致,则将新数据设定给atomic的数据,返回true,表明成功;否则就不设定,并返回false。
    • 对于AtomicInteger、AtomicLong还提供了一些特别的方法。getAndIncrement( )、incrementAndGet( )、getAndDecrement( )、decrementAndGet ( )、addAndGet( )、getAndAdd( )以实现一些加法,减法原子操作。(注意 --i、++i不是原子操作,其中包含有3个操作步骤:第一步,读取i;第二步,加1或减1;第三步:写回内存)

     

    volatile保证可见性

    一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:

    1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。

    2)禁止进行指令重排序。

    先看一段代码,假如线程1先执行,线程2后执行:

    //线程1
    boolean stop = false;
    while(!stop){
        doSomething();
    }

    //线程2
    stop = true;
    这段代码是很典型的一段代码,很多人在中断线程时可能都会采用这种标记办法。但是事实上,这段代码会完全运行正确么?即一定会将线程中断么?不一定,也许在大多数时候,这个代码能够把线程中断,但是也有可能会导致无法中断线程(虽然这个可能性很小,但是只要一旦发生这种情况就会造成死循环了)。

    下面解释一下这段代码为何有可能导致无法中断线程。在前面已经解释过,每个线程在运行过程中都有自己的工作内存,那么线程1在运行的时候,会将stop变量的值拷贝一份放在自己的工作内存当中。

    那么当线程2更改了stop变量的值之后,但是还没来得及写入主存当中,线程2转去做其他事情了,那么线程1由于不知道线程2对stop变量的更改,因此还会一直循环下去。

    但是用volatile修饰之后就变得不一样了:

    使用volatile关键字会强制将修改的值立即写入主存;

    使用volatile关键字的话,当线程2进行修改时,会导致线程1的工作内存中缓存变量stop的缓存行无效(反映到硬件层的话,就是CPU的L1或者L2缓存中对应的缓存行无效);

    由于线程1的工作内存中缓存变量stop的缓存行无效,所以线程1再次读取变量stop的值时会去主存读取。

    那么在线程2修改stop值时(当然这里包括2个操作,修改线程2工作内存中的值,然后将修改后的值写入内存),会使得线程1的工作内存中缓存变量stop的缓存行无效,然后线程1读取时,发现自己的缓存行无效,它会等待缓存行对应的主存地址被更新之后,然后去对应的主存读取最新的值。

    那么线程1读取到的就是最新的正确的值。

     

    volatile不能确保原子性

    下面看一个例子:

    public class Test {
        public volatile int inc = 0;

        public void increase() {
            inc++;
        }

        public static void main(String[] args) {
            final Test test = new Test();
            for(int i=0;i<10;i++){
                new Thread(){
                    public void run() {
                        for(int j=0;j<1000;j++)
                            test.increase();
                    };
                }.start();
            }

            while(Thread.activeCount()>1)  //保证前面的线程都执行完
                Thread.yield();
            System.out.println(test.inc);
        }
    }
    大家想一下这段程序的输出结果是多少?也许有些朋友认为是10000。但是事实上运行它会发现每次运行结果都不一致,都是一个小于10000的数字。

    可能有的朋友就会有疑问,不对啊,上面是对变量inc进行自增操作,由于volatile保证了可见性,那么在每个线程中对inc自增完之后,在其他线程中都能看到修改后的值啊,所以有10个线程分别进行了1000次操作,那么最终inc的值应该是1000*10=10000。

    这里面就有一个误区了,volatile关键字能保证可见性没有错,但是上面的程序错在没能保证原子性。可见性只能保证每次读取的是最新的值,但是volatile没办法保证对变量的操作的原子性。

    在前面已经提到过,自增操作是不具备原子性的,它包括读取变量的原始值、进行加1操作、写入工作内存。那么就是说自增操作的三个子操作可能会分割开执行,就有可能导致下面这种情况出现:

    假如某个时刻变量inc的值为10,

    线程1对变量进行自增操作,线程1先读取了变量inc的原始值,然后线程1被阻塞了;

    然后线程2对变量进行自增操作,线程2也去读取变量inc的原始值,由于线程1只是对变量inc进行读取操作,而没有对变量进行修改操作,所以不会导致线程2的工作内存中缓存变量inc的缓存行无效,也不会导致主存中的值刷新,所以线程2会直接去主存读取inc的值,发现inc的值时10,然后进行加1操作,并把11写入工作内存,最后写入主存。

    然后线程1接着进行加1操作,由于已经读取了inc的值,注意此时在线程1的工作内存中inc的值仍然为10,所以线程1对inc进行加1操作后inc的值为11,然后将11写入工作内存,最后写入主存。

    那么两个线程分别进行了一次自增操作后,inc只增加了1。

    根源就在这里,自增操作不是原子性操作,而且volatile也无法保证对变量的任何操作都是原子性的。

    解决方案:可以通过synchronized或lock,进行加锁,来保证操作的原子性。也可以通过AtomicInteger。

    在java 1.5的java.util.concurrent.atomic包下提供了一些原子操作类,即对基本数据类型的 自增(加1操作),自减(减1操作)、以及加法操作(加一个数),减法操作(减一个数)进行了封装,保证这些操作是原子性操作。atomic是利用CAS来实现原子性操作的(Compare And Swap),CAS实际上是利用处理器提供的CMPXCHG指令实现的,而处理器执行CMPXCHG指令是一个原子性操作。

     

    volatile保证有序性

    在前面提到volatile关键字能禁止指令重排序,所以volatile能在一定程度上保证有序性。

    volatile关键字禁止指令重排序有两层意思:

    1)当程序执行到volatile变量的读操作或者写操作时,在其前面的操作的更改肯定全部已经进行,且结果已经对后面的操作可见;在其后面的操作肯定还没有进行;

    2)在进行指令优化时,不能将在对volatile变量的读操作或者写操作的语句放在其后面执行,也不能把volatile变量后面的语句放到其前面执行。

    可能上面说的比较绕,举个简单的例子:

    //x、y为非volatile变量
    //flag为volatile变量

    x = 2;        //语句1
    y = 0;        //语句2
    flag = true;  //语句3
    x = 4;         //语句4
    y = -1;       //语句5
    由于flag变量为volatile变量,那么在进行指令重排序的过程的时候,不会将语句3放到语句1、语句2前面,也不会讲语句3放到语句4、语句5后面。但是要注意语句1和语句2的顺序、语句4和语句5的顺序是不作任何保证的。

    并且volatile关键字能保证,执行到语句3时,语句1和语句2必定是执行完毕了的,且语句1和语句2的执行结果对语句3、语句4、语句5是可见的。

    那么我们回到前面举的一个例子:

    //线程1:
    context = loadContext();   //语句1
    inited = true;             //语句2

    //线程2:
    while(!inited ){
      sleep()
    }
    doSomethingwithconfig(context);
    前面举这个例子的时候,提到有可能语句2会在语句1之前执行,那么久可能导致context还没被初始化,而线程2中就使用未初始化的context去进行操作,导致程序出错。

    这里如果用volatile关键字对inited变量进行修饰,就不会出现这种问题了,因为当执行到语句2时,必定能保证context已经初始化完毕。

     

    资料整理来自:
    https://blog.csdn.net/it_dx/article/details/70045286 
    https://www.cnblogs.com/stephen0923/p/4505902.html
    http://www.jasongj.com/java/thread_safe/

    展开全文
  • synchronized volatile 的区别是什么?

    千次阅读 2019-05-28 10:50:49
    synchronized volatile 的区别是什么? 作用: synchronized 表示只有一个线程可以获取作用对象的锁,执行代码,阻塞其他线程。 volatile 表示变量在 CPU 的寄存器中是不确定的,必须从主存中读取。保证多...

    synchronized 和 volatile 的区别是什么?

    作用:

    • synchronized 表示只有一个线程可以获取作用对象的锁,执行代码,阻塞其他线程。
    • volatile 表示变量在 CPU 的寄存器中是不确定的,必须从主存中读取。保证多线程环境下变量的可见性;禁止指令重排序。

     

    区别:

    • synchronized 可以作用于变量、方法、对象;volatile 只能作用于变量。
    • synchronized 可以保证线程间的有序性(猜测是无法保证线程内的有序性,即线程内的代码可能被 CPU 指令重排序)、原子性和可见性;volatile 只保证了可见性和有序性,无法保证原子性。
    • synchronized 线程阻塞,volatile 线程不阻塞。

     


    【Java面试题与答案】整理推荐

     

    展开全文
  • 【JAVA】volatile和synchronized的区别

    万次阅读 2018-08-07 19:45:45
    volatile和synchronized的区别 共性:volatile与synchronized都用于保证多线程中数据的安全 区别: (1)volatile修饰的变量,jvm每次都从主存(主内存)中读取,而不会从寄存器(工作内存)中读取。 而...

    共性:

    volatile与synchronized都用于保证多线程中数据的安全

    区别:

    (1)volatile修饰的变量,jvm每次都从主存(主内存)中读取,而不会从寄存器(工作内存)中读取。

    而synchronized则是锁住当前变量,同一时刻只有一个线程能够访问当前变量

    (2)volatile仅能用在变量级别,而synchronized可用在变量和方法中

    (3)volatie仅能实现变量的修改可见性,无法保证变量操作的原子性。而synchronized可以实现变量的修改可见性与原子性


    【1】可见性

    说的是一个线程如果更改了某个变量的值,其他线程能够立刻知道这个变量更改后的值

    【2】原子性

    一个操作要么全做,要么全不做,就像不可分割的原子一样。银行转账这个操作必须具有原子性,A转账给B1000元,A账户减去1000元,B账户加上1000元,两个操作不可分割,不可单独出现,否则会出现意料之外的结果。


    例:volatile int  i=0;并且大量线程调用i的自增操作,那么volatile可以保证变量的安全吗?

    不可以保证,volatile不能保证变量操作的原子性,自增操作包括三个步骤,分别是读取,加一,写入,由于这三个子操作的原子性不能被保证,那么n个线程总共调用n次i++的操作后,最后的i的值并不是大家想的n,而是一个比n小的数

    解释:比如A线程执行自增操作,刚读取到i的初始值0,然后就被阻塞了

    B线程现在开始执行,还是读取到i的初始值0,执行自增操作,此时i的值为1

    然后A线程阻塞结束,对刚才拿到的0执行加一与写入操作,执行成功后,i的值被写成1了,

    我们预期输出2,可是输出的是1,输出比预期小。

    代码验证

    package day0807;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class VolatileTest {
        public volatile int i = 0;
    
        public void increase() {
            i++;
        }
    
        public static void main(String args[]) throws InterruptedException {
            List<Thread> threadList = new ArrayList<>();
            VolatileTest test = new VolatileTest();
            for (int j = 0; j < 10000; j++) {
                Thread thread = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        test.increase();
                    }
                });
                thread.start();
                threadList.add(thread);
            }
    
            //等待所有线程执行完毕
            for (Thread thread : threadList) {
                thread.join();
            }
            System.out.print(test.i);
        }
    }
    

    输出为

    (4)volatile不需要加锁,因此不会造成线程的阻塞,而且比synchronized更轻量级,而synchronized可能导致线程的阻塞

    展开全文
  • 在多线程并发编程中synchronized关键字volatile关键字都有重要意义,volatile是轻量级的synchronized; 加了volatile关键字的变量都属于临界资源; 什么是同步:同一时刻只能有一个线程对资源进行访问; 什么是...
  • volatile和synchronized的区别

    千次阅读 2019-06-08 15:39:18
    文章目录一、volatile二、synchronized三、区别 一、volatile 它所修饰的变量不保留拷贝,直接访问主内存中的。 在Java内存模型中,有main memory,每个线程也有自己的memory (例如寄存器)。为了性能,一个线程会在...
  • violate

    2020-07-31 11:26:01
    Violate 内存模型相关概念 Java内存模型是一种抽象的概念,并不是真实存在的。JVM运行程序的实体是线程,每一个线程都有自己私有的工作内存。Java内存模型中规定了所有变量都存储在主内存中,主内存是一块共享内存...
  • VIOLATE

    2020-07-31 21:16:16
    Violate (1)内存模型相关概念 Java内存模型是一种抽象的概念,并不是真实存在的。JVM运行程序的实体是线程,每一个线程都有自己私有的工作内存。Java内存模型中规定了所有变量都存储在主内存中,主内存是一块共享...
  • 原子性:同一时刻,只有一个线程...但是volatile只能修饰变量,synchronized可以修饰变量、代码块、方法(volatile保证变量可见性,synchronized保证代码块可见性)。 2.volatile用于解决变量多线程之间的可见性...
  • 在开发当中使用多线程的,经常会用到synchronized和volatitle。接下来就讲讲他们的使用场景。 synchronized java关键字,方法用到这个关键字则对这个方法进行加锁。一次只能进入一个线程,其他线程只能等待或执行...
  • java的 violate synchronize

    千次阅读 2014-09-30 17:53:22
    假如没有synchronized,即便被赋值的变量只是一个int, 是原子操作,(即第二个线程要么读到更新之前的值,要么读到更新之后的值,不会读到某种中间状态), 其实还有可见性的问题,即之后的线程可能读还是旧值,从应用...
  • 文章目录1.volatile1.1 并发编程三特性1.1.1 原子性1.1.2 可见性1.1.3 有序性1.2 计算机内存模型(硬件)1.3 Java内存模型(软件)...基本数据类型的访问读写都是具有原子性,当然longdouble的非原子性协定除外。 i
  • 最近一直在想C#中volatile...然后查到了下面这篇JAVA中关于volatile和synchronized关键字的概述,总算对volatile和synchronized关键字有了个大概的了解,而C#中应该类似,注意C#中没有synchronized关键字,但是有M...
  • synchronized和volatile区别

    千次阅读 2018-04-01 22:04:25
    synchronized和volatile区别 个人理解JMM:Java Memory Model(Java内存模型),根据并发过程中如何处理、可见性、原子性和有序性这三个特性而建立的模型。 可见性:JMM提供了volatile变量定义、final、synchronized...
  • /*线程安全的两个方面:执行控制内存可见。 * 执行控制的目的是控制代码执行(顺序)及是否可以并发执行。 * 内存可见控制的是线程执行结果在内存中对其它线程的可见性。 * 根据Java内存模型的实现,线程在具体...
  • 文章目录使用上的区别对原子性的保证对可见性的保证对有序性的保证其他 使用上的区别 volatile关键字只能修饰实例变量或者类变量,...由于synchronized是一种排他的机制,因此被synchronized关键字修饰的同步代码是不能
  • 在多线程并发中synchronized和volatile都扮演着重要的角色,volatile是轻量级的synchronized,volatile保证了共享变量的`可见性`(当一个线程修改共享变量时,另一个线程能比较后读取到变动后的值),它比...
  • synchronized 关键字 volatile 关键字是两个互补的存在,而不是对立的存在: volatile关键字是线程同步的轻量级实现,所以volatile性能肯定比synchronized关键字要好。但是volatile关键字只能用于变量而...
  • violate关键字

    2021-01-25 19:54:59
    Violate关键字 引用:https://www.cnblogs.com/dolphin0520/p/3920373.html 这篇博客讲的比较好
  • Synchronized和Violatile的本质区别? Synchronized本质上是JVM在字节码中加入了锁来实现线程安全。性能较差。 Violatile的本质是JVM在字节码中加入了内存屏障来实现程序的有序性。 而JVM在jdk1.5中,加入了happen-...
  • Java violate变量

    千次阅读 2016-04-11 19:51:16
    Java语言是支持多线程的,为了解决线程并发的问题,在语言内部引入了 同步块 volatile 关键字机制。   synchronized  同步块大家都比较熟悉,通过 synchronized 关键字来实现,所有加上synchronized
  • synchronized,lockvolatile的区别

    千次阅读 2019-07-31 17:24:55
    1、synchronized Java语言的关键字,可用来给对象方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码。当两个并发线程访问同一个对象object中的...
  • 一、Synchronized锁重入 1、Synchronized关键字拥有所锁重入功能,也就是在使用Synchronized的时候,当一个线程获得一个对象的锁之后,在该锁里执行代码时再次请求该对象的锁,可以再次获得该对象的锁。也就是说当...
  • java中volatile、synchronized和lock解析

    千次阅读 2019-02-27 18:14:16
    在研究并发程序时,我们需要了解java中关键字volatile和synchronized关键字的使用以及lock类的用法。 首先,了解下java的内存模型: (1)每个线程都有自己的本地内存空间(java栈中的帧)。线程执行时,先把变量从...
  • violate详解

    2020-10-14 09:21:53
    Why:屏蔽各种硬件操作系统的内存访问差异 JMM是Java内存模型,也就是Java Memory Model,简称JMM,本身是一种抽象的概念,实际上并不存在,它描述的是一组规则或规范,通过这组规范定义了程序中各个变量(包括...
  • synchronized、volatile、Lock详解

    万次阅读 2018-04-18 11:04:42
      在Java并发编程过程中,我们难免会遇到synchronized、volatilelock,其中lock是一个类,而其余两个则是Java关键字。以下记录了小博开发过程中对这三者的理解,不足之处请多指教。 关于线程与进程请参考博文...
  • volatile与synchronized

    2020-05-01 21:50:14
    volatile与synchronized 数据库事务的特性 1.原子性 原子性指的是一个操作不可中断,要么全部执行成功要么全部执行失败。即多个线程一起执行时,一个操作一旦开始,就不会被其他线程干扰。 由原子性变量操作read,...
  • 在多线程并发编程中synchronized和volatile都扮演着重要的角色,synchronized一直是元老级角色,很多人都会称呼它为重量级锁。但是,随着Java SE 1.6对synchronized进行了各种优化之后,有些情况下它就并不那么重了...
  • 轻量级synchronized

    2011-09-19 10:59:23
    后台admin给用户加分,点的快了,会加两次分,在前台没限制的情况下,后台又不想用synchronized可以有两种解决办法 自己模块的util类加个 volatile的static变量 [code="java"] public static ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 678
精华内容 271
关键字:

voliate和synchronized