实现Runnable接口--策略模式的应用
程序员文章站
2022-05-26 07:49:55
...
前言
实现Runnable接口是启动多线程最常见的方式, 而这个过程中我们实则使用了策略模式
策略模式UML图
策略模式有以上角色: 抽象策略(Strategy)), 具体策略, 环境上下文(Context), 其中Context角色依赖Strategy
一个策略模式案例
@FunctionalInterface
// Strategy角色, 也是函数式接口
public interface Strategy {
double calculate(double salary, double bonus);
}
// Context 上下文环境, 依赖Strategy
public class TaxCalculator {
// 工资
private final double salary;
// 奖金
private final double bonus;
// 计税策略
private Strategy strategy;
public TaxCalculator(double salary, double bonus, Strategy strategy) {
this.salary = salary;
this.bonus = bonus;
this.strategy = strategy;
}
public double getSalary() {
return salary;
}
public double getBonus() {
return bonus;
}
protected double calculate(){
return strategy.calculate(salary,bonus);
}
}
// 测试类, 用Lambda表达式表示具体策略实例
public class Test {
public static void main(String[] args) {
TaxCalculator calculator1 = new TaxCalculator(10000d, 2000d,
(salary, bonus) -> salary * 0.1 + bonus * 0.15);
TaxCalculator calculator2 = new TaxCalculator(15000d, 4000d,
(salary, bonus) -> salary * 0.15 + bonus * 0.20);
System.out.println(calculator1.calculate());
System.out.println(calculator2.calculate());
}
}
一个实现Runnable接口启动多线程的实例
// Runnable就是抽象策略接口, 本类就是具体策略类, run() 方法封装了具体实现
public class TicketWindowRunnable implements Runnable {
private int index = 1;
private final static int MAX = 1000;
public void run() {
while (index <= MAX){
System.out.println(Thread.currentThread() + "的号码是" + (index++));
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
// 模拟银行柜台叫号, Thread类可对照策略模式中的 Context角色
public class Bank2 {
public static void main(String[] args) {
final TicketWindowRunnable ticketWindow = new TicketWindowRunnable();
// 依赖具体Strategy 角色
Thread t1 = new Thread(ticketWindow,"1号窗口");
Thread t2 = new Thread(ticketWindow,"2号窗口");
Thread t3 = new Thread(ticketWindow,"3号窗口");
t1.start();
t2.start();
t3.start();
}
}
// 参考Thread类的start()方法源码, 着重关注 start0() 方法
public synchronized void start() {
if (threadStatus != 0)
throw new IllegalThreadStateException();
group.add(this);
boolean started = false;
try {
start0(); // 这是个native方法, 会调用具体策略中的 run() 方法, 并开启线程
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
}
}
}
总结
与策略模式做类比可以更好地理解通过实现Runnable接口启动多线程的写法
把Thread类看做Context上下文角色, Runnable接口看做抽象策略角色, 而具体策略角色由开发者自己定义(也就是重写run方法)
开启多线程的方法: new Thread(Runnable runnable, String name). start()
, 对照Context角色依赖Strategy角色的方式就很好理解了
上一篇: python 的列表遍历删除实现代码
下一篇: gif 动画图像生成与压缩