java并发之固定对象与实例

java并发之固定对象与实例

Immutable Objects

An object is considered immutable if its state cannot change after it is constructed. Maximum reliance on immutable objects is widely accepted as a sound strategy for creating simple, reliable code.

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.

Programmers are often reluctant to employ immutable objects, because they worry about the cost of creating a new object as opposed to updating an object in place. The impact of object creation is often overestimated, and can be offset by some of the efficiencies associated with immutable objects. These include decreased overhead due to garbage collection, and the elimination of code needed to protect mutable objects from corruption.

The following subsections take a class whose instances are mutable and derives a class with immutable instances from it. In so doing, they give general rules for this kind of conversion and demonstrate some of the advantages of immutable objects.

译文:
固定对象
  如果一个对象在创建之后它的状态就不能改变了,那么它就是一个固定对象。固定对象的最大可信性作为一种简单的、可信性的编码被广泛接受。
  固定对象通常应用在并发的应用程序中。由于他们不能改变状态,因此他们不能被线程中断打断或者观察到不一致的状态。
  程序员经常拒绝使用固定对象,因为他们担心创建一个对象会比更新一个对象更加耗费。创建对象的耗费经常被过高估计,并且固定对象的使用能够引起一些效率问题。这些包括减少必要的垃圾回收,和在并发时消除代码需要保护固定对象的开销。
  在下一节中,给定了一个固定对象的类和一个可变对象的类。他们给定了一些通用的转换规则,并且描述了一些固定对象的优势。

A Synchronized Class Example

The class, SynchronizedRGB, defines objects that represent colors. Each object represents the color as three integers that stand for primary color values and a string that gives the name of the color.

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 must be used carefully to avoid being seen in an inconsistent state. Suppose, for example, a thread executes the following code:

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

If another thread invokes color.set after Statement 1 but before Statement 2, the value of myColorInt won't match the value of myColorName. To avoid this outcome, the two statements must be bound together:

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

This kind of inconsistency is only possible for mutable objects — it will not be an issue for the immutable version ofSynchronizedRGB.


译文:
一个同步的例子
这个类,SynchronizedRGB,定义颜色对象的类。每一个对象包括三个颜色需要的基本的值和他们的字符串性质的名字。
复制代码
 1 public class SynchronizedRGB {
 2 
 3     // Values must be between 0 and 255.
 4     private int red;
 5     private int green;
 6     private int blue;
 7     private String name;
 8 
 9     private void check(int red,
10                        int green,
11                        int blue) {
12         if (red < 0 || red > 255
13             || green < 0 || green > 255
14             || blue < 0 || blue > 255) {
15             throw new IllegalArgumentException();
16         }
17     }
18 
19     public SynchronizedRGB(int red,
20                            int green,
21                            int blue,
22                            String name) {
23         check(red, green, blue);
24         this.red = red;
25         this.green = green;
26         this.blue = blue;
27         this.name = name;
28     }
29 
30     public void set(int red,
31                     int green,
32                     int blue,
33                     String name) {
34         check(red, green, blue);
35         synchronized (this) {
36             this.red = red;
37             this.green = green;
38             this.blue = blue;
39             this.name = name;
40         }
41     }
42 
43     public synchronized int getRGB() {
44         return ((red << 16) | (green << 8) | blue);
45     }
46 
47     public synchronized String getName() {
48         return name;
49     }
50 
51     public synchronized void invert() {
52         red = 255 - red;
53         green = 255 - green;
54         blue = 255 - blue;
55         name = "Inverse of " + name;
56     }
57 }
复制代码
SynchronizedRGB必须在不一致的状态下必须谨慎使用。假如,例如,一个线程执行如下代码:
复制代码
1 SynchronizedRGB color =
2     new SynchronizedRGB(0, 0, 0, "Pitch Black");
3 ...
4 int myColorInt = color.getRGB();      //Statement 1
5 String myColorName = color.getName(); //Statement 2
复制代码

如果另外一个线程在语句一执行之后语句二执行之前又另外一个线程执行color.set方法。myColorInt的值将会匹配myColorName的值。为了避免这种情况发生,这两天语句需要绑到一起。

复制代码
synchronized (color) {
    int myColorInt = color.getRGB();
    String myColorName = color.getName();
}
复制代码

这种不一致唯一可能引起的可变对象,对于固定对象来说这是永远不会发生的。

 
 
 
 
 
 
 
 
 
 
 


作者:Janne Lee 
邮箱:JanneLeeMAC@gmail.com 
出处:http://www.cnblogs.com/accipiter/ 
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 
该文章也同时发布在我的独立博客中-Accipter'blog

 
分类: java
原文地址:https://www.cnblogs.com/Leo_wl/p/3267197.html