zoukankan      html  css  js  c++  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();
    }

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

     
     
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    AS3的内存泄漏与垃圾回收
    Unity序列化和持久化
    首发|创业3年半,做8款App全部扑街;转做公众号5个月,零成本吸粉12万还拿了百万天使轮
    为什么成功的人都不太要脸?
    浅谈2040年的职业环境应该是怎么样的?
    2040年的职业环境应该是怎么样的?
    潮汕牛肉火锅,美味在你身边
    要闻:2016胡润百富榜昨天发布 宝能姚振华从炸油条到千亿身家“大黑马”
    海报设计灵感:简约独特的图形图案排版 by Quim Marin
    摄影的基础美学详解
  • 原文地址:https://www.cnblogs.com/accipiter/p/3267078.html
Copyright © 2011-2022 走看看