代码修订与功能更新:

- 新增策略模式示例:在设计模式包中引入策略模式(StrategyPattern),实现支付策略的灵活选择与执行。
- 单例模式示例更新:优化购物车示例,引入线程安全的单例模式实现,并调整类定义与实例化过程。
- 处理线程池执行异常:在ThreadDemo1中处理线程池执行时的异常情况,确保任务异常(如除零错误)时程序的稳定运行。
- 另外,修正了一些代码中的笔误并进行了格式化处理,以保持代码的清晰与规范。
This commit is contained in:
kyriewhluo 2024-08-23 18:26:39 +08:00
parent 8f722ebb0c
commit ffa1d4435b
4 changed files with 423 additions and 55 deletions

View File

@ -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();
} }
} }

View 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);
}
}

View 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;
}
}
}

View File

@ -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();
}
}