Concurrent Programming in Java 才翻5页就充满疑惑的代码,大家帮忙分析分析

04-11-01 newjoy
书上说这段代码解决了并发问题:但我横看竖看还是有问题呀:

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);
  }
}
<p>

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

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

Azure_2003
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
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
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
2004-11-02 13:33
你的担心是多余的:

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

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

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

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

猜你喜欢
2Go 1 2 下一页