找回密码
 FreeOZ用户注册
查看: 1358|回复: 7
打印 上一主题 下一主题

讨论一下下面的多线程程序问题

[复制链接]
跳转到指定楼层
1#
发表于 4-8-2009 22:48:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?FreeOZ用户注册

x
下面的程序摘自《Java Concurrency in Practice》
  1. @ThreadSafe
  2. public class PrimeGenerator implements Runnable {
  3.      @GuardedBy("this")
  4.      private final List<BigInteger> primes
  5.              = new ArrayList<BigInteger>();
  6.      private  volatile boolean cancelled;

  7.      public void run() {
  8.          BigInteger p = BigInteger.ONE;
  9.          while (!cancelled ) {
  10.              p = p.nextProbablePrime();
  11.              synchronized (this) {
  12.                  primes.add(p);
  13.              }
  14.          }
  15.      }

  16.      public void cancel() { cancelled = true;  }

  17.      public synchronized List<BigInteger> get() {
  18.          return new ArrayList<BigInteger>(primes);
  19.      }
  20. }
复制代码
按照我本来我想法,我是没有想到用volatile的,而是采用synchronized的方法来保护cancel的存取,
包括run()方法里,也采用类似getCancel()这样的方案。显然,作者提供的这种volatile的方案
的粒度更小,代价更小(volatile的代价可以看这里:http://www.javaperformancetuning.com/news/qotm030.shtml)。

不知道大家有没有其他看法。
回复  

使用道具 举报

2#
发表于 4-8-2009 22:58:17 | 只看该作者
Java本以为自己不需要volatile关键字,却遇上了多线程编程中的无解难题,只好乖乖地引入
不过总起来说Java的并发模型还是很牛的,新的C++标准也基本上clone了Java的这个并发控制模型。
回复  

使用道具 举报

3#
 楼主| 发表于 4-8-2009 23:06:57 | 只看该作者
原帖由 coredump 于 4-8-2009 22:58 发表
Java本以为自己不需要volatile关键字,却遇上了多线程编程中的无解难题,只好乖乖地引入
不过总起来说Java的并发模型还是很牛的,新的C++标准也基本上clone了Java的这个并发控制模型。


core同学的url没贴好。。
Java的线程控制非常简单好用,的确设计得不错。
不过,从1.5开始,为了支持hardware级的线程控制,加入了java.util.concurrent包,
这真不知道是谁在学谁了
回复  

使用道具 举报

4#
发表于 5-8-2009 08:42:35 | 只看该作者
@ThreadSafe 是什么,我的java知识只是停留在1.4,好像没见过。

FYI: .net compact framework下所有变量自动为volatile。
回复  

使用道具 举报

5#
 楼主| 发表于 5-8-2009 08:53:42 | 只看该作者
@ThreadSafe是这本书的作者弄的annotation
的确是1.5之后的语法
不过specific到这个@ThreadSafe则是作者自制的

而常用的“官方”Annotation如 @Override,@Deprecated,@SuppressWarning(这个不确定)
JPA Annotation有:@Entity, @OneToMany之类

原帖由 procoder 于 5-8-2009 08:42 发表
@ThreadSafe 是什么,我的java知识只是停留在1.4,好像没见过。

FYI: .net compact framework下所有变量自动为volatile。
回复  

使用道具 举报

6#
发表于 5-8-2009 10:45:53 | 只看该作者
volatile的关键是它牺牲了部分锁的特性换来了一点性能的优势。


正确使用 Volatile 变量
http://www.ibm.com/developerworks/cn/java/j-jtp06197.html

其中一个限制就是volatile变量不能用来作为对象引用计数器(不能单独使用volatile),但是在你这个例子中cancelled 是可以的,因为cancel()函数只写入不读取。
如果是addref()这样的操作就只能加上synchronized修饰了

评分

参与人数 1威望 +30 收起 理由
key + 30 谢谢分享!

查看全部评分

回复  

使用道具 举报

7#
 楼主| 发表于 5-8-2009 11:06:50 | 只看该作者
原帖由 coredump 于 5-8-2009 10:45 发表
volatile的关键是它牺牲了部分锁的特性换来了一点性能的优势。


正确使用 Volatile 变量
http://www.ibm.com/developerworks/cn/java/j-jtp06197.html

其中一个限制就是volatile变量不能用来作为对象引用计数 ...


你的理解应该是正确的,但表达似乎有点含糊。
volatile变量的重要条件是该变量的值变化不依赖于之前的状态,这也就是你说的“读”的情况。
不知道你同不同意我的看法

评分

参与人数 1威望 +10 收起 理由
coredump + 10 同意,完整的说法在那个链接里,所以我就没 ...

查看全部评分

回复  

使用道具 举报

8#
发表于 5-8-2009 23:14:06 | 只看该作者

回复 #7 key 的帖子

C++中的volatile概念和Java中的差不多,但是C++中的volatile麻烦更多,不同平台(cpu, compiler...)行为差异更多,所以这东西貌似对多线程编程引起的麻烦比带来的好处更多。更彻底的并发方案应该还是STM。
回复  

使用道具 举报

您需要登录后才可以回帖 登录 | FreeOZ用户注册

本版积分规则

小黑屋|手机版|Archiver|FreeOZ论坛

GMT+10, 20-4-2025 22:44 , Processed in 0.042090 second(s), 25 queries , Gzip On, Redis On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表