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,定义颜色对象的类。每一个对象包括三个颜色需要的基本的值和他们的字符串性质的名字。
 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

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

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

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

 
 
 
 
 
 
 
 
 
 
 

【翻译十五】-java并发之固定对象与实例的更多相关文章

  1. java并发之固定对象与实例

    java并发之固定对象与实例 Immutable Objects An object is considered immutable if its state cannot change after ...

  2. 【翻译十八】java-并发之锁对象

    Lock Objects Synchronized code relies on a simple kind of reentrant lock. This kind of lock is easy ...

  3. Java进阶(三十五)java int与integer的区别

    Java进阶(三十五)java int与Integer的区别 前言 int与Integer的区别从大的方面来说就是基本数据类型与其包装类的区别: int 是基本类型,直接存数值,而Integer是对象 ...

  4. Java进阶(二十五)Java连接mysql数据库(底层实现)

    Java进阶(二十五)Java连接mysql数据库(底层实现) 前言 很长时间没有系统的使用java做项目了.现在需要使用java完成一个实验,其中涉及到java连接数据库.让自己来写,记忆中已无从搜 ...

  5. Java学习笔记二十五:Java面向对象的三大特性之多态

    Java面向对象的三大特性之多态 一:什么是多态: 多态是同一个行为具有多个不同表现形式或形态的能力. 多态就是同一个接口,使用不同的实例而执行不同操作. 多态性是对象多种表现形式的体现. 现实中,比 ...

  6. 【翻译十四】java-并发之保护块儿

    Guarded Blocks Threads often have to coordinate their actions. The most common coordination idiom is ...

  7. Java 并发之共享对象

    上一篇文章说的是,避免多个线程在同一时间访问对象中的同一数据,这篇文章来详细说说共享和发布对象. 在没有同步的情况下,我们无法预料编译器.处理器安排操作执行的顺序,经常会发生以为“一定会”发生的动作实 ...

  8. Java进阶(四十五)java 字节流与字符流的区别

    java 字节流与字符流的区别(转载)   字节流与和字符流的使用非常相似,两者除了操作代码上的不同之外,是否还有其他的不同呢?   实际上字节流在操作时本身不会用到缓冲区(内存),是文件本身直接操作 ...

  9. java基础(十五)----- Java 最全异常详解 ——Java高级开发必须懂的

    本文将详解java中的异常和异常处理机制 异常简介 什么是异常? 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常. Java异常的分类和类结构图 1.Java中的所 ...

随机推荐

  1. ajax初探01

    1.为什么使用ajax ajax使用异步处理模型,意味着在浏览器等待数据加载期间,用户可以做其他事情 在页面正在加载时使用ajax:使用ajax,浏览器可以向服务器请求一些数据,并且一旦数据请求发出, ...

  2. jquery 生成table表格 部分代码

    想生成上面这样的table表格先看返回数据格式 <div id="create_img_tab"></div> window.onload = functi ...

  3. treeiso

    主要包括了一些树同构的代码和一些树图生成器... download

  4. 用普通用户通过sudo进行启动tomcat时报如下异常

    用普通用户通过sudo进行启动tomcat时报如下异常 tomcat user 不在 sudoers 文件中.此事将被报告. 这是由于sudo命令使用root用户执行命令.而处于安全性的考虑,一般不允 ...

  5. iOS keyChain 的使用

    详细资料,请参看苹果官方文档Keychain Services Reference . ios中的keychain,用于保存用户的机密信息,对keychain的操作有4种,就是 增,删,改,查: Se ...

  6. delphi的取整函数round、trunc、ceil和floor

    delphi的取整函数round.trunc.ceil和floor 首先引入math单元 uses math; 1.Round(四舍六入五留双) 功能说明:对一个实数进行四舍五入.(按照银行家算法) ...

  7. percona-toolkit 之 【pt-slave-delay】说明

    摘要: 在主从复制的架构中,正常情况下主上操作的记录也会在从上进行操作,虽说是异步复制,但操作会“实时”的同步到从.比如在主上不小心误操作了,还没等反应过来从上也会马上执行误操作,后期只有通过二进制或 ...

  8. ubuntu vsftp 安装

    1.输入sudo apt-get install vsftpd 回车 这样就安装完毕了,然后去建立一个ftp的帐号,我这里使用的是ftp. 2.输入useradd ftp 回车 输入密码 回车 这样帐 ...

  9. Effective C++ -----条款42:了解typename的双重意义

    声明template参数时,前缀关键字class和typename可互换. 请使用关键字typename标识嵌套从属类型名称:但不得在base class lists(基类列)或member init ...

  10. codeforces 425C Sereja and Two Sequences(DP)

    题意读了好久才读懂....不知道怎么翻译好~~请自便~~~ http://codeforces.com/problemset/problem/425/C 看懂之后纠结好久...不会做...仍然是看题解 ...