论坛首页 Java企业应用论坛

java并发线程-----阻塞队列的实现和思考

浏览 17457 次
精华帖 (3) :: 良好帖 (0) :: 新手帖 (2) :: 隐藏帖 (6)
作者 正文
   发表时间:2011-07-07  
samttsch 写道
volatile 只保证可见性,不能保证原子性

"在那些非原子且可由多个线程访问的易变操作中,一定不能够依赖于 volatile 的同步机制,相反,要使用 java.util.concurrent 包的同步语句、锁类和原子类。它们在设计上能够保证程序是线程安全的。"

你说的有一定的道理,但是不全对。
0 请登录后投票
   发表时间:2011-07-07  
。。这可不是我说的
0 请登录后投票
   发表时间:2011-07-07  
volatile 其实就是表示这个变量每次读或写的时候都会从主存中读到线程的堆栈中

所谓可见性,即:其他线程的每次修改,我都是可以看到的
例如: i++;

每次都会从主存中读取i的值,在线程中执行++,然后将新值写回到主存中
假设有两个线程A B
i的值为 10
A读取值为10,执行++,得到11(注意还未写入主存)
B此时读取值也是10,执行++,并写入主存
A此时再写入主存,此时A知道i的值被其他线程修改过,但是仍然会写入主存,于是就覆盖了其他线程的修改。

简单测试:
public class Test2
{
    public static void main(String[] args)
    {
        Thread[] threads = new Thread[1000];
        for(int i=0;i<threads.length;i++){
            threads[i] = new IncrementThread();
        }
        for(int i=0;i<threads.length;i++){
            threads[i].start();
        }
        System.out.println(IncrementThread.i);
    }
}
class IncrementThread extends Thread {
    public static volatile int i = 0;
    public void run(){
        i++; //i++ 不是原子操作
    }
}




0 请登录后投票
   发表时间:2011-07-08  
zhangbenben 写道
samttsch 写道
volatile 只保证可见性,不能保证原子性

"在那些非原子且可由多个线程访问的易变操作中,一定不能够依赖于 volatile 的同步机制,相反,要使用 java.util.concurrent 包的同步语句、锁类和原子类。它们在设计上能够保证程序是线程安全的。"

你说的有一定的道理,但是不全对。


应该没有人这么说过吧,难道没有java.util.concurrent包之前,java都没有同步机制了?

另外补充说明一下楼上的代码,代码注释中专门说明了i++不是原子操作,这意味着代码的运行结果会是不正常的的、不可预知的结果。
0 请登录后投票
   发表时间:2011-07-08  
volatile 不是同步机制 ok?

在那些非原子且可由多个线程访问的易变操作中,一定不能够依赖于 volatile 的同步机制,相反,要使用 java.util.concurrent 包的同步语句、锁类和原子类。它们在设计上能够保证程序是线程安全的

这句话我是引用IBM developverwork上的文章中的总结。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics