原型模式

一、背景

      如果存在这么个场景,多个线层需要操作(读写)某一对象,但是每个线程之间希望互不影响。就像银行给客户发送邮件,邮件的模板都是一样的,我们可以抽象为一个邮件类,但是发送给每个人的称呼是不一样的,如果采用单线程发送,那么如果发送量比较大的话就会很慢。采用多线程发送,就会存在这样的问题,线程一还没发送,线程二就将邮件的称呼修改了,这样就会导致线程不安全的问题。原型模式正好能解决这样的问题。每个线程拷贝一份邮件对象,各自对拷贝邮件对象操作,相互之间互不影响。

二、概念

    原型模式:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。java Object已经提供了一个clone方法,原型模式在java中实现更为简单快捷。

三、代码实例

package prototypePattern;

import java.util.Random;

/**
 * 邮件类
 * 
 */
class Mail implements Cloneable {

	private String acceptName;// 收件人
	private String context;// 内容

	public String getAcceptName() {
		return acceptName;
	}

	public void setAcceptName(String acceptName) {
		this.acceptName = acceptName;
	}

	public String getContext() {
		return context;
	}

	public void setContext(String context) {
		this.context = context;
	}

	@Override
	protected Mail clone() throws CloneNotSupportedException {
		Mail mail = (Mail) super.clone();
		return mail;
	}
}

/**
 * 发送邮件的线程
 * 
 */
class SendMail implements Runnable {
	private Mail mail;

	public SendMail(Mail mail) {
		this.mail = mail;
	}

	@Override
	public void run() {
		try {
			Mail mailClone = this.mail.clone();// 拷贝对象
			String name = getRandName();
			mailClone.setAcceptName(name);
			mailClone.setContext(name + "您好,邮件内容。。。。");
			System.out.println(Thread.currentThread().getName() + "发送邮件给-》"
					+ mailClone.getAcceptName() + ",内容为:"
					+ mailClone.getContext());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static String getRandName() {
		String source = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		StringBuffer sb = new StringBuffer();
		Random rand = new Random();
		for (int i = 0; i < 3; i++) {
			sb.append(source.charAt(rand.nextInt(source.length())));
		}
		return sb.toString();
	}
}

public class MailSendCli {
	public static void main(String[] args) {
		Mail mail = new Mail();// 邮件模板对象
		SendMail sender1 = new SendMail(mail);
		Thread tSender1 = new Thread(sender1, "发送线程1");

		SendMail sender2 = new SendMail(mail);
		Thread tSender2 = new Thread(sender2, "发送线程2");

		SendMail sender3 = new SendMail(mail);
		Thread tSender3 = new Thread(sender3, "发送线程3");

		tSender1.start();
		tSender2.start();
		tSender3.start();
	}
}

大家可以将mailClone换成mail试一下就会发现,称呼和邮件内容的称呼可能就会不一致。这里顺便提一下,java 里的clone是浅拷贝,所谓浅拷贝是不对对象中的引用类型拷贝,只会对基本数据类型进行拷贝。浅拷贝对应的是深拷贝(即引用类型也可拷贝),大家可以通过重写clone方法实现自己对象的深拷贝。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值