美文网首页
【The Java™ Tutorials】【Concurrenc

【The Java™ Tutorials】【Concurrenc

作者: Ppian | 来源:发表于2018-04-19 14:17 被阅读0次

Immutable object

An object is considered immutable if its state cannot change after it is constructed.

Immutable objects are particularly useful in concurrent applications. Since they cannot change state, they cannot be corrupted by thread interference or observed in an inconsistent state.

很多人不喜欢用immutable object,因为他们担心新建一个对象比更新一个对象的开销更大。创建对象的开销经常被高估,而immutable object带来的效率经常被忽略。使用immutable object可以降低垃圾回收的开销,可以不用写专门的代码来避免线程冲突和不一致性。

A Synchronized Class Example

public class SynchronizedRGB {

    // Values must be between 0 and 255.
    private int red;
    private int green;
    private int blue;
    private String name;

    private void check(int red,
                       int green,
                       int blue) {
        if (red < 0 || red > 255
            || green < 0 || green > 255
            || blue < 0 || blue > 255) {
            throw new IllegalArgumentException();
        }
    }

    public SynchronizedRGB(int red,
                           int green,
                           int blue,
                           String name) {
        check(red, green, blue);
        this.red = red;
        this.green = green;
        this.blue = blue;
        this.name = name;
    }

    public void set(int red,
                    int green,
                    int blue,
                    String name) {
        check(red, green, blue);
        synchronized (this) {
            this.red = red;
            this.green = green;
            this.blue = blue;
            this.name = name;
        }
    }

    public synchronized int getRGB() {
        return ((red << 16) | (green << 8) | blue);
    }

    public synchronized String getName() {
        return name;
    }

    public synchronized void invert() {
        red = 255 - red;
        green = 255 - green;
        blue = 255 - blue;
        name = "Inverse of " + name;
    }
}

我们必须小心使用SynchronizedRGB才能避免不一致性。比如在一个线程中执行以下代码:

SynchronizedRGB color =
    new SynchronizedRGB(0, 0, 0, "Pitch Black");
...
int myColorInt = color.getRGB();      //Statement 1
String myColorName = color.getName(); //Statement 2

如果执行完Statement 1的时候,另一个线程改变了该对象的状态,那么Statement 2就会得到一个不一致的name。所以必须把Statement 1和Statement 2绑定在一起,才能该问题:

synchronized (color) {
    int myColorInt = color.getRGB();
    String myColorName = color.getName();
} 

A Strategy for Defining Immutable Objects

下面的规则定义了一个创建immutable objects的简单策略,但是并不一定所有的immutable class都是使用以下规则实现的。

  1. 不提供setter方法;
  2. 对所有的fields使用finalprivate关键字;
  3. 让子类不允许重写方法。最简的方式是把类定义为final,一个更复杂的方式将构造函数定义为private,然后使用工厂模式构造实例。
  4. 如果实例域引用了mutable object,不能允许这些objects被改变:
    • 不要提供改变这些mutable objects的方法;
    • 不用共享这些mutable objects的引用。不要保存传递给构造函数的外部的mutable object的引用,如果需要,可以创建一份copy,然后保存copy的引用。同样的,在需要的时候创建内部的mutable object的copy,保存该copy的引用。

我们使用以上规则,将SynchronizedRGB修改为如下:

final public class ImmutableRGB {

    // Values must be between 0 and 255.
    final private int red;
    final private int green;
    final private int blue;
    final private String name;

    private void check(int red,
                       int green,
                       int blue) {
        if (red < 0 || red > 255
            || green < 0 || green > 255
            || blue < 0 || blue > 255) {
            throw new IllegalArgumentException();
        }
    }

    public ImmutableRGB(int red,
                        int green,
                        int blue,
                        String name) {
        check(red, green, blue);
        this.red = red;
        this.green = green;
        this.blue = blue;
        this.name = name;
    }


    public int getRGB() {
        return ((red << 16) | (green << 8) | blue);
    }

    public String getName() {
        return name;
    }

    public ImmutableRGB invert() {
        return new ImmutableRGB(255 - red,
                       255 - green,
                       255 - blue,
                       "Inverse of " + name);
    }
}

相关文章

网友评论

      本文标题:【The Java™ Tutorials】【Concurrenc

      本文链接:https://www.haomeiwen.com/subject/hjgzhftx.html