随笔-204  评论-149  文章-0  trackbacks-0

http://www.javaeye.com/topic/109150

http://itchaser.javaeye.com/blog/440335

http://www.javaeye.com/topic/11315


还得了解一下Java内存模型。。。

看了一下Java虚拟机规范,就比较清楚了

posted on 2009-06-28 00:50 Frank_Fang 阅读(1146) 评论(5)  编辑  收藏 所属分类: Java编程

评论:
# re: Java volatile关键字语义 2009-07-01 21:45 | Frank_Fang

package test.thread.two;



/**
 * 你会发现next( )和getValue( )都是synchronized。如果你只对其中一个做synchronized,那么另一个就被忽略了,于是其它线程就能肆无忌惮地调用它了。
 * 一定要记住:所有访问共享资源的方法都必须是synchronized的,否则程序肯定会出错。
 * 而invariant( )倒不是synchronized的,这是因为它是供测试线程用的,因此我们希望它能随时被调用,只有这样才能算是真正的测试。
 *
 
*/


public class SynchronizedEvenGenerator implements Invariant {
    
    
//不管加不加volatile都会发生冲突,只有将getValue()前加上synchronized才不会发生冲突
     private  volatile int i;

    
public synchronized void next() {
        i
++;
        i
++;
    }


    
//假如这个方法的synchronized去掉了,发生冲突是必然的
    
//你可能听说过,为了提高性能,在读或写原子数据的时候,你应该避免使用同步。
    //这个建议是非常危险而错误的

    public synchronized int getValue() {
        
return i;
    }


    
// Not synchronized so it can run at
    
// any time and thus be a genuine test:
    public InvariantState invariant() {
        
int val = getValue();
        
if (val % 2 == 0)
            
return new InvariantOK();
        
else
            
return new InvariantFailure(new Integer(val));
    }


    
public static void main(String[] args) {
        SynchronizedEvenGenerator gen 
= new SynchronizedEvenGenerator();
        
new InvariantWatcher(gen, 4000); // 4-second timeout
        while (true)
            gen.next();
    }

}

原子操作

"原子操作(atomic operation)是不需要synchronized",这是Java多线程编程的老生常谈了。所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行倒结束,中间不会有任何context switch(切换到另一个线程)。

通常所说的原子操作包括对非longdouble型的primitive进行赋值,以及返回这两者之外的primitive。之所以要把它们排除在外是因为它们都比较大,而JVM的设计规范又没有要求读操作和赋值操作必须是原子操作(JVM可以试着去这么作,但并不保证)。不过如果你在longdouble前面加了volatile,那么它就肯定是原子操作了。

如果你一知半解地把这条规则用到SynchronizedEvenGenerator.java上,就会发觉:

public synchronized int getValue() { return i; }

好像很符合原子操作的定义嘛。但是把synchronized去掉试试看,程序很快就出了错。这是因为,虽然return i是原子操作,但删掉synchronized之后,别的线程就能在它还处于不稳定状态的时候读到它了。在做这种优化之前,先得真正弄懂这么做的后果是什么。这里没有现成的经验。

  回复  更多评论
  
# re: Java 内存模型及 volatile关键字语义 2009-07-21 01:56 | tt
@Frank_Fang

这段代码在哪里?如何才可以运行测试

我在另外一个网站上看到的不是如此  回复  更多评论
  
# re: Java 内存模型及 volatile关键字语义 2009-07-21 01:57 | tt
http://hi.baidu.com/lifa868/blog/item/22bc7718926ad772dbb4bd0e.html

这里讲的,即时非long及double也未必一会是原子的。。。
还有代码中说://不管加不加volatile都会发生冲突,只有将getValue()前加上synchronized才不会发生冲突

会这样么?  回复  更多评论
  
# re: Java 内存模型及 volatile关键字语义 2009-07-24 10:55 | Frank_Fang
volatile保证了线程间变量的可见性,但是不保证能够进行互斥访问
synchronized保证对变量的互斥访问,当进入或者退出synchronized代码块时会对将线程中的此本地变量副本(这个要区别TSD)写到主存中,这也确保不同线程间对此变量的修改可见性
  回复  更多评论
  
# re: Java 内存模型及 volatile关键字语义 2009-09-04 10:59 | gee
@Frank_Fang
楼上正解  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: