• 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();
    	}
    }
    
  • 相关阅读:
    NSHashtable and NSMaptable
    架构的本质:构造定律与结合规则
    软件复用的基础和形式
    架构模式:循环模式、管道模式
    待整理
    functions and closures are reference types-函数和闭包是引用类型
    @autoclosure-可以让表达式自动封装成一个闭包:输入的是一个表达式
    Python 运算符优先级
    Linux下chkconfig命令详解
    Linux下Redis开机自启(Centos)
  • 原文地址:https://www.cnblogs.com/nadou/p/13985577.html
Copyright © 2020-2023  润新知