Java—裝飾者設計模式
阿新 • • 發佈:2020-11-17
一、裝飾者設計模式
概念:可以擴充套件原有物件的功能(比繼承更靈活),即定義一個介面
二、使用多執行緒為例子
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();
}
}