java多线程学习心得——concurrent programming in java读书笔记

对象方法内加锁的三原则:

1. 对于更新对象方法内部成员的时候,一定要加锁。

2. 读取对象内部可能被更新的状态字段的时候,加锁。

3. 在调用其他对象方法的时候,千万别加锁。(目的是防止互锁,而且避免锁住当前对象)


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

public Particle(int x, int y) {
this.x = x;
this.y = y;
}

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

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

上面的例子中很清晰的遵守了三原则,move()方法本质上就是更新内部状态,所以整个方法加锁。请注意rng是一个final状态的内部对象,所以在synchronized方法中调用rng的方法并不会造成性能问题。而draw方法则避免了对整个方法加锁,因为我们不清楚g.drawRect是否被堵塞,所以用local variable读出内部状态之后,对象的锁就被释放掉,代码更加清晰。

 

Java中的多线程主要是通过Thread类实现的,很常见的使用方式是在Thread类的contructor中传入一个Runnable的Interface, 而且大部分Runnable的实现是基于匿名类,好处在于匿名类可以自如的使用上下文中变量(只有声明为final的变量才可以被使用)而无需定义繁琐的getter。

public class ParticleApplet extends Applet {
protected Thread[] threads = null;
protected final ParticleCanvas canvas = new ParticleCanvas(100);

protected Thread makeThread(final Particle p) //declare as final
{
Runnable runloop = new Runnable() { 
public void run() //the method defined in Runnable interface
{
try {
for(;;){
p.move();
canvas.repaint();
Thread.sleep(100);
}
catch(InterruptedException e) { return//exit by receiving interruption exception}
};
return new Thread(runLoop); //create new thread
}


 

posted on 2012-11-26 14:46  梁霄  阅读(295)  评论(0)    收藏  举报

导航