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并发之固定对象与实例的更多相关文章
- 【翻译十五】-java并发之固定对象与实例
Immutable Objects An object is considered immutable if its state cannot change after it is construct ...
- Java 并发之共享对象
上一篇文章说的是,避免多个线程在同一时间访问对象中的同一数据,这篇文章来详细说说共享和发布对象. 在没有同步的情况下,我们无法预料编译器.处理器安排操作执行的顺序,经常会发生以为“一定会”发生的动作实 ...
- Java中的匿名对象代码实例
/* 匿名对象:就是没有名字的对象. 匿名对象的应用场景: A:调用场景,仅仅只调用一次的时候. 注意:调用多次的时候,不合适. 那么,这种匿名调用有什么好处吗? 有,匿名对象调用完毕就是垃圾.可以被 ...
- Java访问子类对象的实例变量
对于Java这种语言来说,一般来说,子类可以调用父类中的非private变量,但在一些特殊情况下, Java语言可以通过父类调用子类的变量 具体的还是请按下面的例子吧! package com.yon ...
- 【Java学习】类、对象、实例—类是对象的抽象,对象是类的实例
类.对象.实例的关系是什么,如果不能很好的理解什么是类什么是对象就无法讲清楚, 类:某种事物与另一种事物具有相似性,比如哈士奇和泰迪,我们发现他们有一些相似的特性和行为,在生物学上,他们都属于“狗”, ...
- 深入理解Java并发之synchronized实现原理
深入理解Java类型信息(Class对象)与反射机制 深入理解Java枚举类型(enum) 深入理解Java注解类型(@Annotation) 深入理解Java类加载器(ClassLoader) 深入 ...
- Java内存区域与对象创建过程
一.java内存区域 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有的区域则 ...
- Java生成MD5加密字符串代码实例
这篇文章主要介绍了Java生成MD5加密字符串代码实例,本文对MD5的作用作了一些介绍,然后给出了Java下生成MD5加密字符串的代码示例,需要的朋友可以参考下 (1)一般使用的数据库中都会保存用 ...
- java入门---变量类型&类变量&局部变量&实例变量&静态变量
在Java语言中,所有的变量在使用前必须声明.声明变量的基本格式如下: type identifier [ = value][, identifier [= value] ...] ; ...
随机推荐
- poj3070--Fibonacci(矩阵的高速幂)
Fibonacci Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9650 Accepted: 6856 Descrip ...
- gnu 扩展之#和##
转自:http://chongsoft.bokee.com/5816474.html 今天测试了宏定义中的 "#" 和 "##" 的区别. 结果如下: &quo ...
- git上自然框架源码
[自然框架]终于把源码弄到git上吗了 2015-02-02 14:38 by 金色海洋(jyk)阳光男孩, 183 阅读, 6 评论, 收藏, 编辑 好久没写博客了,发现又从左面的排名里掉出去了. ...
- 安卓CTS官方文档之兼容性方案概览
兼容性方案概览 安卓的兼容性方案让安卓手机生产商能够很容易就开发中可兼容的安卓设备(天地会珠海分舵注:可兼容什么呢?就是可以兼容标准google提供的安卓系统可以支持的功能,以防手机生产商把开源的安卓 ...
- 利用docker搭建yii2 详细步骤
定位镜像 在hub.docker.com 搜索yii2,并且最后定位到 https://hub.docker.com/r/codemix/yii2-base/codemix/yii2-base 然后在 ...
- 关于session_start()这个问题
关于session_start()这个问题,其实网上很多解决的方法,论坛也好多人回答这类的问题, 现在的状况是依然有警告提示Warning: session_start() [function.ses ...
- 快速构建Windows 8风格应用19-基础控件II
原文:快速构建Windows 8风格应用19-基础控件II 本篇博文接着上篇博文<快速构建Windows 8风格应用18-基础控件I>介绍开发Windows 8风格应用中常用控件. Sli ...
- Atitit.升级软件的稳定性---基于数据库实现持久化 循环队列 循环队列
Atitit.升级软件的稳定性---基于数据库实现持久化 循环队列 环形队列 1. 前言::选型(马) 1 2. 实现java.util.queue接口 1 3. 当前指针的2个实现方式 1 1.1 ...
- 清空SQL Server数据库中所有表数据的方法
原文:清空SQL Server数据库中所有表数据的方法 其实删除数据库中数据的方法并不复杂,为什么我还要多此一举呢,一是我这里介绍的是删除数据库的所有数据,因为数据之间可能形成相互约束关系,删除操作可 ...
- 在SSIS中使用自定义的DLL文件
原文:在SSIS中使用自定义的DLL文件 步骤1.开发dll(需要签名) using System;using System.Collections.Generic;using System.Text ...