immutable模式--想破坏也破坏不了

定义:

immutable模式存在着确保实例状态不发生改变的类。在访问这些事例时不需要执行互斥的处理。

引例:

这是一个使用了immutable模式的小例子。

类的一览表
名字说明
person人的类
main测试行为类
printpersonthread显示person示例的线程类
/* *
 * 1.final class Person ,final斌不是Person一定的,Person不能被继承,防止被修改。
 * 2.字段没有set方法,所以不能被改变
 * */
public final class Person {
	private final String name;
	private final String address;

	public Person(String name, String address) {
		this.name = name;
		this.address = address;
	}

	public String getName() {
		return name;
	}

	public String getAddress() {
		return address;
	}

	public String toString() {
		return "[ Person: name = " + name + ", address = " + address + " ]";
	}
}
public class PrintPersonThread extends Thread {
	private Person person;

	public PrintPersonThread(Person person) {
		this.person = person;
	}

	public void run() {
		while (true) {
			System.out.println(Thread.currentThread().getName() + " prints " + person);
		}
	}
}
public class Main {
	public static void main(String[] args) {
		Person alice = new Person("Alice", "Alaska");
		new PrintPersonThread(alice).start();
		new PrintPersonThread(alice).start();
		new PrintPersonThread(alice).start();
	}
}

结果: 

Thread-5 prints [ Person: name = Alice, address = Alaska ]
Thread-5 prints [ Person: name = Alice, address = Alaska ]
Thread-5 prints [ Person: name = Alice, address = Alaska ]
Thread-5 prints [ Person: name = Alice, address = Alaska ]
Thread-5 prints [ Person: name = Alice, address = Alaska ]

 immutable模式中的角色

immutable角色是一个类,在这个类中字段是不能被修改的,也不存在修改的方法。immutable角色的实例一旦被创建,状态就不再改变,无需做互斥处理。

tips: java中final含义:

final类无法扩展,没有子类。final方法在子类中不能被重写。final的字段不能多次赋值。

何时使用

实例创建后状态不发生变化时。实例是共享的,且被经常访问。

零碎的知识点:

arraylist类是线程不安全的。copyonwritearraylist和collections.synchronizedlist是安全的。

性能测试题:

Single Threaded Execution模式中我们使用synchronized保证线程安全的,有些时候可以用immutable保证线程的安全。我么做一个性能的测试。

/*测试同步与非同步的区别*/
public class Main {
	private static final long CALL_COUNT = 10000000L;

	public static void main(String[] args) {
		trial("NotSynch", CALL_COUNT, new NotSynch());
		trial("Synch", CALL_COUNT, new Synch());
	}

	private static void trial(String msg, long count, Object obj) {
		System.out.println(msg + ": BEGIN");
		long start_time = System.currentTimeMillis();
		for (long i = 0; i < count; i++) {
			obj.toString();
		}
		System.out.println(msg + ": END");
		System.out.println("Elapsed time = " + (System.currentTimeMillis() - start_time) + "msec.");
	}
}

class NotSynch {
	private final String name = "NotSynch";

	public String toString() {
		return "[ " + name + "]";
	}
}

class Synch {
	private final String name = "Synch";

	public synchronized String toString() {
		return "[ " + name + "]";
	}
}

NotSynch: BEGIN
NotSynch: END
Elapsed time = 114msec.
Synch: BEGIN
Synch: END
Elapsed time = 1595msec.  

从这个测试我们看出。两者的性能差的还是挺大。 

思考题:

明明没有setter方法,却不是immutable类

public final class UserInfo {
	private final StringBuffer info;

	public UserInfo(String name, String address) {
		this.info = new StringBuffer("<info name=\"" + name + "\" address=\"" + address + "\" />");
	}

	public StringBuffer getInfo() {
		// 外部也可以改变info的值
		return info;
	}

	public String toString() {
		return "[ UserInfo: " + info + " ]";
	}
}
public class Main {
	public static void main(String[] args) {
		// 制作实体
		UserInfo userinfo = new UserInfo("Alice", "Alaska");

		// 显示
		System.out.println("userinfo = " + userinfo);

		// 状态变更
		StringBuffer info = userinfo.getInfo();
		info.replace(12, 17, "Bobby"); // "Alice"竚琌12..16

		// 再度显示
		System.out.println("userinfo = " + userinfo);
	}
}

结果大家自己试一试。

判断是不是immutable类?

public final class ImmutablePerson {
	private final String name;
	private final String address;

	public ImmutablePerson(String name, String address) {
		this.name = name;
		this.address = address;
	}

	public ImmutablePerson(MutablePerson person) {
//person可能会变
		this.name = person.getName();
		this.address = person.getAddress();
	}

	public MutablePerson getMutablePerson() {
		/* 通过this构造,保证了数据一致 */
		return new MutablePerson(this);
	}

	public String getName() {
		return name;
	}

	public String getAddress() {
		return address;
	}

	public String toString() {
		return "[ ImmutablePerson: " + name + ", " + address + " ]";
	}
}

如何更改?

public final class ImmutablePerson {
	private final String name;
	private final String address;

	public ImmutablePerson(String name, String address) {
		this.name = name;
		this.address = address;
	}

	// 不可变
	public ImmutablePerson(MutablePerson person) {
		synchronized (person) {
			this.name = person.getName();
			this.address = person.getAddress();
		}
	}

	public MutablePerson getMutablePerson() {
		return new MutablePerson(this);
	}

	public String getName() {
		return name;
	}

	public String getAddress() {
		return address;
	}

	public String toString() {
		return "[ ImmutablePerson: " + name + ", " + address + " ]";
	}
}

具体的原理自己体会!so easy 对不。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值