java设计模式(二)

4、

管程:在说管程之前先说说这样一个概念——在多线程环境下,当一个对象的方法被多于一个线程同时访问时,可能会造成不正确或不规则的行为,这里有一个专用的名词称为“线程同步”,这里的“同”指的是对资源的共享。而管程机制顾名思义便是对线程的管理(这是我自己的理解,可能有不周到之处。),它可以通过这样的一个对象上获取一个锁以保证在任意一个时刻只有一个线程被允许执行该对象的任何方法,即线程被排队。那这样一种对象由谁来实现呢?在java中大概有三种方法,其中一种是通过在对象方法的声明中使用synchronized关键字来做到这一点。

下面是一个简单的消息日志记录器,用来在多线程的环境记录日志消息,其他对象可以通过调用一个Filelog实例的log方法来在日志文件中写入日志消息。因为使用了synchronized关键字,所以在log方法内部,Filelog执行必需的文件操作来将一条输入消息记入日志。

public class Filelog {
public synchronized void log(String msg){
	DataOutputStream dos=null;
	try{
		dos=new DataOutputStream(new FileOutputStream("log.txt",true));
		dos.writeBytes(msg);
		dos.close();
	}catch(Exception ef){
		ef.printStackTrace();
	}
}
}

 

 

Synchronized关键字保证了在任意一个时间点上将只有一个线程被允许在一个给定的Filelog对象上执行log方法。

第三部分——创建模式

创建模式中有工厂方法、单例、抽象工厂、原型、生成器五种模式。

1、工厂方法和单例的原理是一样的,都是将所需的功能封装在称为“工厂方法”的指定方法中,在“工厂方法”中创建实例,设计工厂方法最简单的方式之一便是创建一个声明工厂方法的抽象类或接口。而单例模式即是确保始终有且仅有一个特定对象的实例,其他与工厂方法模式的设计基本相同。不要认为单例模式过于局限,在应用中有工厂方法模式就可以了。其实则不然,单例模式是很有用的,比如在应用程序中可能只需要一个数据库连接对象,这种情况下单例模式便确保了始终只有一个对象实例,而且保证了对此对象实例的一致性访问。

之前我们用“管程”来解决了线程同步问题,在这里使用单例也可以有效地解决这一问题,我认为在单例模式的设计中主要有三点:

(1)static的使用

(2)设计专用构造器(所谓专用构造器即将构造器设计为私有的——防止客户机对象通过调用其构造器创建对象)

(3)Synchronized关键字的使用

下面就之前的记录消息日志文件的例子来具体实施单例模式:

      先创建一个接口Logger(这里也可以使用抽象父类,只不过由于JAVA的单继承性使得一个类只能继承一个父类,而一个类可以继承多个接口),在此接口中声明Filelog中所用到的log方法(在接口中声明所用到的所有方法,这些方法都是抽象的):

public interface Logger {
	//使用接口声明所用到的所有方法
 public void log(String msg);
}

 

    

然后创建记录日志消息的类

Filelog(为确保单例模式使用到了staticsynchronized):

public class Filelog implements Logger{
private static Filelog logger;
//专用构造器
private Filelog(){
	
}
public static Filelog getFilelog(){
	if(logger==null){
		logger=new Filelog();
	}
	return logger;
}
public synchronized void log(String msg){
	DataOutputStream dos=null;
	try{
		dos=new DataOutputStream(new FileOutputStream("log.txt",true));
		dos.writeBytes(msg);
		dos.close();
	}catch(Exception ef){
		ef.printStackTrace();
	}
}
}

 

再设计一个工厂类LoggerFactory来获取一个Filelog实例(这里不是通过构造函数获得而要使用getInstance获得Filelog实例):

 

 

public class LoggerFactory {
public Logger getLogger(){
	return Filelog.getFilelog();
}
}

 

  

测试程序:

public class LoggerTest {
public static void main(String args[]){
	LoggerFactory factory=new LoggerFactory();
	//用factory对象创建所需的方法
	Logger logger=factory.getLogger();
	logger.log("A message to log");
}
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值