Java—装饰者设计模式

一、装饰者设计模式

概念:可以扩展原有对象的功能(比继承更灵活),即定义一个接口


二、使用多线程为例子

2.1 接口中需要返回值,如何做?

public class Demo {
	public static void main(String[] args) {
		new Runnable() {
			
			@Override
			public void run() {
				// 此方法中需要返回对象,如何做
				// 可以通过成员变量的方式来获取,需要新写一个子类来实现Runnable接口
				
			}
		};
	}
}

解决方法:

Runnable的实现类

public class MyRunnable implements Runnable{
	
	public String result;

	@Override
	public void run() {
 		// 但是代码写死了,如何改?
		result = "hello world!";
	}

}

测试类

public class Demo {
	public static void main(String[] args) throws Exception {
		MyRunnable runnable = new MyRunnable();
		
		Thread t1 = new Thread(runnable);
		t1.start();
		// 等待线程结束,获取result不为null;
		// 否则,main方法开启线程,线程有可能未执行完成,就执行main中接下来的代码
		t1.join();
		System.out.println(runnable.result);
	}
}

2.2 接口中的返回值不能写死,如何做?(使用装饰者设计模式,即定义一个接口来传参)

接口装饰器

/**
 * 装饰器
 * @author hjn
 * @date   2019年12月10日 下午4:59:29
 *
 * @param <T>
 */
public interface Decorator<T> {
	/**
	 * 装饰器
	 * @return 不知道传递的是什么类型;可以使用泛型,可以达到通用的效果
	 */
	T decorator();
}

Runnable的实现类

public class MyRunnable<T> implements Runnable{
	
	public T result;
	
	private Decorator<T> decorator;
	
	// 外部可以通过set方法设置要传递的类型和值
	public void setDecorator(Decorator<T> decorator) {
		this.decorator = decorator;
	}


	@Override
	public void run() {
		// 调用的一定是实现类重写的decorator方法
		result = decorator.decorator();
	}

}

测试类

public class Demo {
	public static void main(String[] args) throws Exception {
		MyRunnable<String> runnable = new MyRunnable<String>();
		runnable.setDecorator(new Decorator<String>() {
			
			@Override
			public String decorator() {
				return "hello world";
			}
		});
		
		MyRunnable<String> runnable2 = new MyRunnable<String>();
		runnable2.setDecorator(new Decorator<String>() {
			
			@Override
			public String decorator() {
				return "java";
			}
		});
		
		Thread t1 = new Thread(runnable);
		Thread t2 = new Thread(runnable2);
		t1.start();
		t2.start();
		// 等待线程结束,获取result不为null;
		// 否则,main方法开启线程,线程有可能未执行完成,就执行main中接下来的代码
		t1.join();
		t2.join();
		System.out.println(runnable.result);
		System.out.println(runnable2.result);
	}
}

但是,以上的程序存在有可能无节制地创建对象;因此,我们可以使用线程池的方法来创建


2.3 解决无节制创建对象

ThreadUtils

/**
 * 多线程工具
 * @author chenwei
 * @date 2019年5月24日 下午4:23:54
 */
public class ThreadUtils {
	/**线程锁*/
	private static ExecutorService threadPool = null;
	/*使用静态代码块,只创建一次*/
	static {
		//获取设备最大线程池
//		threadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
		//获取当前cpu的线程数
		int threadCount = Runtime.getRuntime().availableProcessors();
		threadCount = threadCount <= 1?2:threadCount;//如果cpu只有一条线程默认给予2
		threadPool = new ThreadPoolExecutor(//创建一个有队列的线程池,超出执行线程会放到队列中等待
							threadCount,//
							threadCount*3,//最大线程数
			                60,//空闲线程存活时间
			                TimeUnit.MILLISECONDS,//时间单位
			                new LinkedBlockingQueue<Runnable>(threadCount*3));//队列
	}
	
	/**
	 * 获取线程池对象
	 * 
	 * @author chenwei
	 * @date 2019年5月24日 下午4:24:32
	 * @return
	 */
	public static ExecutorService getThreadPool() {
		return threadPool;
	}
	
	
}

测试类

public class Demo {
	public static void main(String[] args) throws Exception {
		MyRunnable<String> runnable = new MyRunnable<String>();
		runnable.setDecorator(new Decorator<String>() {
			
			@Override
			public String decorator() {
				return "hello world";
			}
		});
		
		MyRunnable<String> runnable2 = new MyRunnable<String>();
		runnable2.setDecorator(new Decorator<String>() {
			
			@Override
			public String decorator() {
				return "java";
			}
		});
		
		ExecutorService threadPool = ThreadUtils.getThreadPool();
		Future<?> submit = threadPool.submit(runnable);
		Future<?> submit2 = threadPool.submit(runnable2);
		
		// Future<?>中的get()为null时,表示线程执行完成
		while(true){
			if(submit.get() == null && submit2.get() == null){
				break;
			}
		}
		
		System.out.println(runnable.result);
		System.out.println(runnable2.result);
		
		// 关闭线程池
		threadPool.shutdown();
	}
}

使用倒计时锁

public class Demo {
	public static void main(String[] args) throws Exception {
		// 倒计时锁 -- 参数执行几个线程就设置几个值
		CountDownLatch countDownLatch = new CountDownLatch(2);
		MyRunnable<String> runnable = new MyRunnable<String>();
		runnable.setDecorator(new Decorator<String>() {
			
			@Override
			public String decorator() {
				// 倒计时,此方法写在线程执行的run方法中
				countDownLatch.countDown();
				return "hello world";
			}
		});
		
		MyRunnable<String> runnable2 = new MyRunnable<String>();
		runnable2.setDecorator(new Decorator<String>() {
			
			@Override
			public String decorator() {
				countDownLatch.countDown();
				return "java";
			}
		});
		
		ExecutorService threadPool = ThreadUtils.getThreadPool();
		Future<?> submit = threadPool.submit(runnable);
		Future<?> submit2 = threadPool.submit(runnable2);
		
		// Future<?>中的get()为null时,表示线程执行完成
//		while(true){
//			if(submit.get() == null && submit2.get() == null){
//				break;
//			}
//		}
		
		// 等待子线程执行结束
		countDownLatch.await();
		
		System.out.println(runnable.result);
		System.out.println(runnable2.result);
		
		// 关闭线程池
		threadPool.shutdown();
	}
}
posted @ 2020-11-17 09:55  娜豆  阅读(108)  评论(0编辑  收藏  举报