JiveJdon Community Forums
在线405人   首页   主题表   培训咨询   标签   精华   查搜   注册    登陆 RSS
首页 » 论坛 » Java多线程 集群 并行模式
???en_US.forumThreadPrev.name??? 上一主题
  Go back to the topic 返回本主题   Go back to the topic listing返回主题列表
???en_US.forumThreadNext.name??? 下一主题
Go 总共有 7 回复 / 1
 发表新帖子   回复该主题贴
newjoy

悄悄话
发表文章: 21
注册时间: 2003年06月21日 11:18
Concurrent Programming in Java 才翻5页就充满疑惑的代码,大家帮忙分析分析 2004年11月01日 21:41 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
标签列表
书上说这段代码解决了并发问题:但我横看竖看还是有问题呀:

import java.util.Random;

class Particle{
protected int x;
protected int y;
protected final Random rng = new Random();

public Particle(int inX,int inY){
x = inX;
y = inY;
}

public synchronized void move(){
x += rng.nextInt(10) - 5 ;
y += rng.nextInt(20) - 10;
}

public void draw(Graphics g){
int lx,ly;
synchronized (this) {lx=x;ly=y;}
g.drawRect(lx,ly,10,10);
}
}

1、由于 move() 与 draw(Graphics g) 方法可能会被两个线程同时调用,那它还是没有解决,“当draw操作使用move方法调用前的y值和move方法调用后的x值绘制一个例子的图形”。

2、protected final Random rng = new Random(); 为什么定义为final?好处具体表现在什么地方?
Azure_2003

悄悄话
发表文章: 95
注册时间: 2004年06月14日 23:43
Re: Concurrent Programming in Java 才翻5页就充满疑惑的代码,大家帮忙分析分析 2004年11月02日 11:33 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
> 1、由于 move() 与 draw(Graphics g)
> 方法可能会被两个线程同时调用,那它还是没有解决,“当dr
> w操作使用move方法调用前的y值和move方法调用后的x值绘制?> 个例子的图形”。

不太明白这段程序要解决的是哪方面的并发,“当draw操作使用move方法调用前的y值和move方法调用后的x值绘制一个例子的图形”。这句话让人不太理解。

>
> 2、protected final Random rng = new Random();
> 为什么定义为final?好处具体表现在什么地方?

个人理解为:定义为final是为了强制让Particle类的一个实例中只能使用一个rng引用,不允许被转移引用指针,也不允许被null,直到该Particle实例被释放时rng引用才被释放掉. 这么做的目的主要是为了程序逻辑上的安全,当然如果你的记忆力比较好,或者你不想多为将来接受这个程序的人做奉献,要不要final都是一样的.
newjoy

悄悄话
发表文章: 21
注册时间: 2003年06月21日 11:18
Re: Concurrent Programming in Java 才翻5页就充满疑惑的代码,大家帮忙分析分析 2004年11月02日 12:08 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
不好意思,写错两个字
“当draw操作使用move方法调用前的y值和move方法调用后的x值绘制一个粒子的图形”。

这儿的并发问题是,若move方法和draw方法同时被连个线程调用。

有可能发现这样的现象:

1、draw 准备绘图时,先获取一个X,
2、同时,move,修改了 x,y的值
4、draw 获取Y,这是获取的X,Y不是一致性的。 只会在一个错误的点显示一个图形。

所以说“当draw操作使用 move方法调用前的y值和move方法调用后的x值绘制一个粒子的图形”。
newjoy

悄悄话
发表文章: 21
注册时间: 2003年06月21日 11:18
Re: Concurrent Programming in Java 才翻5页就充满疑惑的代码,大家帮忙分析分析 2004年11月02日 12:09 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
不好意思,写错两个字
“当draw操作使用move方法调用前的y值和move方法调用后的x值绘制一个粒子的图形”。

这儿的并发问题是,若move方法和draw方法同时被两个线程调用。

有可能发现这样的现象:

1、draw 准备绘图时,先获取一个X,
2、同时,move,修改了 x,y的值
4、draw 获取Y,这是获取的X,Y不是一致性的。 只会在一个错误的点显示一个图形。

所以说“当draw操作使用 move方法调用前的y值和move方法调用后的x值绘制一个粒子的图形”。
Azure_2003

悄悄话
发表文章: 95
注册时间: 2004年06月14日 23:43
Re: Concurrent Programming in Java 才翻5页就充满疑惑的代码,大家帮忙分析分析 2004年11月02日 13:33 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
你的担心是多余的:

synchronized (this) {lx=x;ly=y;}

这里上的对象锁,锁定对象是this,所以在此锁定的工作区域里面操作的时候是不允许其它线程move()的,直到该锁定区域运行完毕,这时候this实例上的对象锁就被释放掉了.move()操作就可以被执行了.

而在move()动作上有一个方法锁,在此方法操作的时候是不允许x值和y值被两个线程乱改的.

因为在写的时候x,y是一致的,而在读的时候该x,y又不允许被修改,所以说它解决了你所担心的这个并发问题
newjoy

悄悄话
发表文章: 21
注册时间: 2003年06月21日 11:18
Re: Concurrent Programming in Java 才翻5页就充满疑惑的代码,大家帮忙分析分析 2004年11月02日 15:58 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
谢谢!
多线程我要补补课啦 :)
newjoy

悄悄话
发表文章: 21
注册时间: 2003年06月21日 11:18
Re: Concurrent Programming in Java 才翻5页就充满疑惑的代码,大家帮忙分析分析 2004年11月02日 16:17 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
那我要想问个问题,下面的代码:

public class QueueThread extends Thread {

private static Logger logger = Logger.getLogger(QueueThread.class.getName());

private PacketQueue packetQueue;
private HashMap packetListeners = new HashMap();

public QueueThread(PacketQueue queue) { packetQueue = queue; }

public boolean addListener(PacketListener listener, String element){
if (listener == null || element == null){
return false;
}
packetListeners.put(listener,element);
return true;
}

public boolean removeListener(PacketListener listener){
packetListeners.remove(listener);
return true;
}

public void run(){

for( Packet packet = packetQueue.pull();
packet != null;
packet = packetQueue.pull()) {

logger.finest("Get One Packet:" + packet);
try {
Packet child;
String matchString;
if (packet.getElement().equals(
"iq")){
child = packet.getFirstChild(
"query");
if (child == null){
matchString =
"iq";
} else {
matchString = child.getNamespace();
}
} else {
matchString = packet.getElement();
}

synchronized(packetListeners){
Iterator iter = packetListeners.keySet().iterator();
while (iter.hasNext()){
PacketListener listener = (PacketListener)iter.next();
String listenerString = (String)packetListeners.get(listener);
if (listenerString.equals(matchString)){
listener.notify(packet);
}
}
}
} catch (Exception ex){
//Log.error("QueueThread: ", ex); // Soldier on - no matter what
}
}
}
}



一旦任意线程进入

synchronized(packetListeners){
Iterator iter = packetListeners.keySet().iterator();
while (iter.hasNext()){
PacketListener listener = (PacketListener)iter.next();
String listenerString = (String)packetListeners.get(listener);
if (listenerString.equals(matchString)){
listener.notify(packet);
}
}
}

代码块,则别的线程调用函数

public boolean addListener(PacketListener listener, String element){
if (listener == null || element == null){
return false;
}
packetListeners.put(listener,element);
return true;
}

执行到
packetListeners.put(listener,element);
处一定是阻塞状态对不?



Azure_2003

悄悄话
发表文章: 95
注册时间: 2004年06月14日 23:43
Re: Concurrent Programming in Java 才翻5页就充满疑惑的代码,大家帮忙分析分析 2004年11月02日 17:47 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
这个主题有 7 回复 / 1Go
???en_US.forumThreadPrev.name??? 上一主题
  Go back to the topic 返回本主题   Go back to the topic listing返回主题列表    返回页首返回页首
???en_US.forumThreadNext.name??? 下一主题
热点TAG: AOP cache 缓存 DDD EJB 集群 设计模式 Hibernate IOC JiveJdon OO RBAC Seam Spring Struts
正在读取,请等待...
google yahoo 新浪ViVi 365Key网摘 天极网摘 CSDN网摘 添加到百度搜藏 POCO网摘 博采网摘
查询本论坛内 回复超过的热门帖子
     回复该主题贴
标题
 
粗体 斜体 下划线 插入图片 插入代码 插入url链接 插入附件
内容
  发贴前查询 标签列表勿重复发表问题

RSS 手机阅读 add to google add to yahoo
解惑之道在J道 ,打造中国最具影响力的的企业软件社区
OpenSource JIVEJDON v3.0 Powered by JdonFramework Code © 2002-08 jdon.com
anti spam