代码修订与功能更新:
- 新增策略模式示例:在设计模式包中引入策略模式(StrategyPattern),实现支付策略的灵活选择与执行。 - 单例模式示例更新:优化购物车示例,引入线程安全的单例模式实现,并调整类定义与实例化过程。 - 处理线程池执行异常:在ThreadDemo1中处理线程池执行时的异常情况,确保任务异常(如除零错误)时程序的稳定运行。 - 另外,修正了一些代码中的笔误并进行了格式化处理,以保持代码的清晰与规范。
This commit is contained in:
parent
8f722ebb0c
commit
ffa1d4435b
@ -1,12 +1,48 @@
|
|||||||
package cn.whaifree.designPattern;
|
package cn.whaifree.designPattern;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
public class SingletonPattern {
|
public class SingletonPattern {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Main{
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Scanner scanner = new Scanner(System.in);
|
||||||
|
HashMap<String, Integer> carHas = ManagerCar.getManagerCar().getCarHas();
|
||||||
|
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
String nextLine = scanner.nextLine();
|
||||||
|
if ("exit".equals(nextLine)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
String[] s = nextLine.split(" ");
|
||||||
|
String obj = s[0];
|
||||||
|
Integer num = Integer.valueOf(s[1]);
|
||||||
|
carHas.put(obj, carHas.getOrDefault(obj, 0) + num);
|
||||||
/**
|
/**
|
||||||
|
* 添加商品到购物车
|
||||||
|
* public void addItem(String name, int quantity) {
|
||||||
|
* items.merge(name, quantity, Integer::sum);
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
carHas.forEach(
|
||||||
|
(s, integer) -> System.out.println(s + " " + integer)
|
||||||
|
);
|
||||||
|
|
||||||
|
scanner.close();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
* https://kamacoder.com/problempage.php?pid=1074
|
* https://kamacoder.com/problempage.php?pid=1074
|
||||||
*
|
*
|
||||||
* 【设计模式专题之单例模式】1.小明的购物车
|
* 【设计模式专题之单例模式】1.小明的购物车
|
||||||
@ -32,9 +68,9 @@ public class SingletonPattern {
|
|||||||
* 使用私有构造函数防止外部直接实例化。
|
* 使用私有构造函数防止外部直接实例化。
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static class ManagerCar{
|
class ManagerCar{
|
||||||
|
|
||||||
private HashMap<String, Integer> carHas = null;
|
public HashMap<String, Integer> carHas = null;
|
||||||
|
|
||||||
public ManagerCar() {
|
public ManagerCar() {
|
||||||
this.carHas = new HashMap<>();
|
this.carHas = new HashMap<>();
|
||||||
@ -57,37 +93,68 @@ public class SingletonPattern {
|
|||||||
return managerCar;
|
return managerCar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class ShoppingCart {
|
||||||
|
|
||||||
|
private static ShoppingCart instance = null;
|
||||||
|
private static ArrayList<String> productNames = new ArrayList<>();
|
||||||
|
private static ArrayList<Integer> productQuantities = new ArrayList<>();
|
||||||
|
|
||||||
|
private ShoppingCart() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ShoppingCart getInstance() {
|
||||||
|
if (instance == null) {
|
||||||
|
synchronized (ManagerCar.class) {
|
||||||
|
if (instance == null) {
|
||||||
|
instance = new ShoppingCart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Add(String name, int quantity) {
|
||||||
|
productNames.add(name);
|
||||||
|
productQuantities.add(quantity);
|
||||||
|
System.out.println(name + " " + quantity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Main1 {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
ShoppingCart cart = ShoppingCart.getInstance();
|
||||||
Scanner scanner = new Scanner(System.in);
|
Scanner scanner = new Scanner(System.in);
|
||||||
HashMap<String, Integer> carHas = ManagerCar.getManagerCar().getCarHas();
|
|
||||||
|
|
||||||
|
String inputLine;
|
||||||
|
while (scanner.hasNextLine()) {
|
||||||
|
inputLine = scanner.nextLine();
|
||||||
|
|
||||||
while (true) {
|
if ("exit".equalsIgnoreCase(inputLine)) {
|
||||||
String nextLine = scanner.nextLine();
|
|
||||||
if ("stop".equals(nextLine)) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
String[] s = nextLine.split(" ");
|
|
||||||
String obj = s[0];
|
|
||||||
Integer num = Integer.valueOf(s[1]);
|
|
||||||
carHas.put(obj, carHas.getOrDefault(obj, 0) + num);
|
|
||||||
/**
|
|
||||||
* 添加商品到购物车
|
|
||||||
* public void addItem(String name, int quantity) {
|
|
||||||
* items.merge(name, quantity, Integer::sum);
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
carHas.forEach(
|
String[] parts = inputLine.split(" ");
|
||||||
(s, integer) -> System.out.println(s + " " + integer)
|
|
||||||
);
|
if (parts.length == 2) {
|
||||||
|
String name = parts[0];
|
||||||
|
int quantity;
|
||||||
|
|
||||||
|
try {
|
||||||
|
quantity = Integer.parseInt(parts[1]);
|
||||||
|
cart.Add(name, quantity);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
System.out.println("输入错误,请重新输入");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
System.out.println("输入错误,请重新输入");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
scanner.close();
|
scanner.close();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
66
src/main/java/cn/whaifree/designPattern/StrategyPattern.java
Normal file
66
src/main/java/cn/whaifree/designPattern/StrategyPattern.java
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
package cn.whaifree.designPattern;
|
||||||
|
|
||||||
|
public class StrategyPattern {
|
||||||
|
|
||||||
|
enum PayType{
|
||||||
|
ALI(1, "阿里", new AliPayStrategy()),
|
||||||
|
WX(2,"微信", new WxPayStrategy());
|
||||||
|
|
||||||
|
int code;
|
||||||
|
String name;
|
||||||
|
PayStrategy payStrategy;
|
||||||
|
|
||||||
|
PayType(int code, String name, PayStrategy payStrategy) {
|
||||||
|
this.code = code;
|
||||||
|
this.name = name;
|
||||||
|
this.payStrategy = payStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PayStrategy getPayStrategy(Integer code) {
|
||||||
|
for (PayType value : values()) {
|
||||||
|
if (value.code == code) {
|
||||||
|
return value.payStrategy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PayStrategy {
|
||||||
|
|
||||||
|
boolean pay();
|
||||||
|
}
|
||||||
|
|
||||||
|
static class AliPayStrategy implements PayStrategy {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean pay() {
|
||||||
|
System.out.println("ali");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class WxPayStrategy implements PayStrategy {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean pay() {
|
||||||
|
System.out.println("wx");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static class PayService {
|
||||||
|
public void pay(Integer code) {
|
||||||
|
PayStrategy payStrategy = PayType.getPayStrategy(code);
|
||||||
|
if (payStrategy != null) {
|
||||||
|
payStrategy.pay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
new PayService().pay(2);
|
||||||
|
}
|
||||||
|
}
|
105
src/main/java/cn/whaifree/leetCode/LinkedList/LeetCode234.java
Normal file
105
src/main/java/cn/whaifree/leetCode/LinkedList/LeetCode234.java
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
package cn.whaifree.leetCode.LinkedList;
|
||||||
|
|
||||||
|
import cn.whaifree.leetCode.model.ListNode;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
|
public class LeetCode234 {
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args) throws InterruptedException {
|
||||||
|
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
map.put("1", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
CountDownLatch countDownLatch = new CountDownLatch(10);
|
||||||
|
|
||||||
|
new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
map.forEach(
|
||||||
|
new BiConsumer<String, Integer>() {
|
||||||
|
@Override
|
||||||
|
public void accept(String s, Integer integer) {
|
||||||
|
System.out.println(s + ":" + integer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
|
||||||
|
new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
map.put("i" + i, i);
|
||||||
|
countDownLatch.countDown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
|
||||||
|
countDownLatch.await();
|
||||||
|
System.out.println(map.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test()
|
||||||
|
{
|
||||||
|
ListNode listNode = ListNode.listNodeFromArray(new int[]{1, 3, 3,2, 1});
|
||||||
|
System.out.println(new Solution().isPalindrome(listNode));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 1. 截取一半
|
||||||
|
* - 逆转、对比
|
||||||
|
* 2. 输出到list中,再回问判断
|
||||||
|
* 3.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Solution {
|
||||||
|
public boolean isPalindrome(ListNode head) {
|
||||||
|
int len = 0;
|
||||||
|
ListNode index = head;
|
||||||
|
while (index != null) {
|
||||||
|
len++;
|
||||||
|
index = index.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
index = head;
|
||||||
|
for (int i = 0; i < len / 2; i++) {
|
||||||
|
index = index.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
ListNode newHead = reverseList(index);
|
||||||
|
|
||||||
|
|
||||||
|
ListNode A = head;
|
||||||
|
ListNode B = newHead;
|
||||||
|
while (B != null) {
|
||||||
|
if (A.val != B.val) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
A = A.next;
|
||||||
|
B = B.next;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ListNode reverseList(ListNode head) {
|
||||||
|
ListNode prev = null;
|
||||||
|
ListNode curr = head;
|
||||||
|
while (curr != null) {
|
||||||
|
ListNode nextTemp = curr.next;
|
||||||
|
curr.next = prev;
|
||||||
|
prev = curr;
|
||||||
|
curr = nextTemp;
|
||||||
|
}
|
||||||
|
return prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
package cn.whaifree.test;
|
package cn.whaifree.test;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.lang.reflect.Proxy;
|
||||||
import java.util.List;
|
import java.util.*;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ public class ThreadDemo1 {
|
|||||||
static class CyclicBarrierDemo2{
|
static class CyclicBarrierDemo2{
|
||||||
|
|
||||||
public static void main(String[] args) throws InterruptedException {
|
public static void main(String[] args) throws InterruptedException {
|
||||||
|
// Proxy.newProxyInstance()
|
||||||
// 每9个cyclicBarrier.await()执行后,都执行一次wait
|
// 每9个cyclicBarrier.await()执行后,都执行一次wait
|
||||||
CyclicBarrier cyclicBarrier = new CyclicBarrier(9,
|
CyclicBarrier cyclicBarrier = new CyclicBarrier(9,
|
||||||
() -> System.out.println("上面的9个执行完了,轮到我了 wait complete!") // 等待前9次执行结束
|
() -> System.out.println("上面的9个执行完了,轮到我了 wait complete!") // 等待前9次执行结束
|
||||||
@ -116,4 +116,134 @@ public class ThreadDemo1 {
|
|||||||
executorService.shutdown();
|
executorService.shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class p2{
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
ExecutorService executorService = Executors.newCachedThreadPool();
|
||||||
|
List<Future<Boolean>> ar = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
int finalI = i;
|
||||||
|
Future<Boolean> submit = executorService.submit(new Callable<Boolean>() {
|
||||||
|
@Override
|
||||||
|
public Boolean call() throws Exception {
|
||||||
|
if (finalI == 3) {
|
||||||
|
throw new MyException();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ar.add(submit);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (Future<Boolean> submit : ar) {
|
||||||
|
submit.get();
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
if (e.getCause() instanceof MyException){
|
||||||
|
System.out.println("我捕获到了");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("1");
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (int count = 1; count <= 5; count++) {
|
||||||
|
if (count == 3) {
|
||||||
|
//故意制造一下异常
|
||||||
|
int num = 1 / 0;
|
||||||
|
} else {
|
||||||
|
System.out.println("count:" + count + " 业务正常执行");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("try catch 在for 外面的情形, 出现了异常,for循环显然被中断");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int count = 1; count <= 5; count++) {
|
||||||
|
try {
|
||||||
|
if (count == 3) {
|
||||||
|
//故意制造一下异常
|
||||||
|
int num = 1 / 0;
|
||||||
|
} else {
|
||||||
|
System.out.println("count:" + count + " 业务正常执行");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("try catch 在for 里面的情形, 出现了异常,for循环显然继续执行");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class MyException extends RuntimeException {
|
||||||
|
|
||||||
|
|
||||||
|
private static ThreadPoolExecutor resetInstanceExecutor = new ThreadPoolExecutor(10, 10, 0L, TimeUnit.MILLISECONDS,
|
||||||
|
new LinkedBlockingQueue<Runnable>(), new ThreadPoolExecutor.CallerRunsPolicy());
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
|
||||||
|
List<String> instance = Arrays.asList("i-12345678", "i-23456789", "i-34567890", "i-45678901", "i-56789012",
|
||||||
|
"i-67890123", "i-78901234", "i-89012345", "i-90123456", "i-101234567");
|
||||||
|
CountDownLatch countDownLatch = new CountDownLatch(10);
|
||||||
|
|
||||||
|
Long startTimestamp = System.currentTimeMillis();
|
||||||
|
|
||||||
|
Map<String, Future<Boolean>> resetInstanceMap = new HashMap<>();
|
||||||
|
boolean exceedRateLimit = false; // 没有被限频
|
||||||
|
for (String instanceId : instance) {
|
||||||
|
Future<Boolean> result = resetInstanceExecutor.submit(new ResetInstanceCallable(instanceId,countDownLatch));
|
||||||
|
resetInstanceMap.put(instanceId, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Map.Entry<String, Future<Boolean>> futureEntry : resetInstanceMap.entrySet()) {
|
||||||
|
try {
|
||||||
|
futureEntry.getValue().get();
|
||||||
|
}
|
||||||
|
catch (MyException ex){
|
||||||
|
System.out.println("my exception"); // Callable内抛出的自定义异常无法被捕获,Callable内抛出的自定义异常无法被捕获
|
||||||
|
// get()方法会抛出一个ExecutionException,而这个异常的cause才是原始的异常
|
||||||
|
exceedRateLimit = true;
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
System.out.println("interrupted");
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
System.out.println("exception");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println(exceedRateLimit==false? "没有超过限制" : "超过限制");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ResetInstanceCallable implements Callable<Boolean> {
|
||||||
|
|
||||||
|
private String instanceId;
|
||||||
|
private CountDownLatch countDownLatch;
|
||||||
|
|
||||||
|
public ResetInstanceCallable(String instanceId, CountDownLatch countDownLatch) {
|
||||||
|
this.instanceId = instanceId;
|
||||||
|
this.countDownLatch = countDownLatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean call() {
|
||||||
|
throw new MyException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user