该提交包括以下主要变更:

1. 新增了`SingletonPattern.java`,实现了购物车管理器的单例模式,用于记录商品添加到购物车的信息,并在购买结束后打印出商品清单。这是针对设计模式专题之单例模式的练习。

2. 新增了`LeetCode138.java`,实现了复制一个包含随机指针的链表。这是对链表操作和复制的练习。

3. 新增了`Proxy.java`,实现了动态代理,用于扣费20作为中介费的案例。这是对Java代理模式的实践。

4. 对`TestCacheThreadPool.java`进行了修改,添加了多个线程安全的示例代码,包括单例模式的实现、ConcurrentHashMap的使用、ReentrantLock和Condition的使用等。这是对多线程和并发编程的探索。

这次提交的代码涵盖了设计模式、链表操作、动态代理和并发编程等多个方面,展示了作者在编程领域的广泛兴趣和实践能力。
This commit is contained in:
kyriewhluo 2024-08-14 20:00:18 +08:00
parent 3aaee55251
commit cd4c443077
4 changed files with 463 additions and 4 deletions

View File

@ -0,0 +1,93 @@
package cn.whaifree.designPattern;
import java.util.HashMap;
import java.util.Scanner;
import java.util.function.BiConsumer;
public class SingletonPattern {
/**
* https://kamacoder.com/problempage.php?pid=1074
*
* 设计模式专题之单例模式1.小明的购物车
* 题目描述
* 小明去了一家大型商场拿到了一个购物车并开始购物请你设计一个购物车管理器记录商品添加到购物车的信息商品名称和购买数量并在购买结束后打印出商品清单在整个购物过程中小明只有一个购物车实例存在
* 输入描述
* 输入包含若干行每行包含两部分信息分别是商品名称和购买数量商品名称和购买数量之间用空格隔开
* 输出描述
* 输出包含小明购物车中的所有商品及其购买数量每行输出一种商品的信息格式为 "商品名称 购买数量"
* 输入示例
* Apple 3
* Banana 2
* Orange 5
* 输出示例
* Apple 3
* Banana 2
* Orange 5
* 提示信息
* 本道题目请使用单例设计模式
*
* 使用私有静态变量来保存购物车实例
*
* 使用私有构造函数防止外部直接实例化
*/
static class ManagerCar{
private HashMap<String, Integer> carHas = null;
public ManagerCar() {
this.carHas = new HashMap<>();
}
public HashMap<String, Integer> getCarHas() {
return carHas;
}
private volatile static ManagerCar managerCar;
public static ManagerCar getManagerCar() {
if (managerCar == null) {
synchronized (ManagerCar.class) {
if (managerCar == null) {
managerCar = new ManagerCar();
}
}
}
return managerCar;
}
}
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 ("stop".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();
}
}

View File

@ -0,0 +1,86 @@
package cn.whaifree.leetCode.LinkedList;
import org.junit.Test;
public class LeetCode138 {
static class Node {
int val;
Node next;
Node random;
public Node(int val) {
this.val = val;
this.next = null;
this.random = null;
}
}
@Test
public void test() {
// 1 2 3
// 1 3
// 2 1
// Node node1 = new Node(1);
// Node node2 = new Node(2);
// Node node3 = new Node(3);
// node1.next = node2;
// node2.next = node3;
// node1.random = node3;
// node2.random = node1;
// Node node = copyRandomList(node1);
// System.out.println(node);
// [[7,null],[13,0],[11,4],[10,2],[1,0]]
Node node1 = new Node(7);
Node node2 = new Node(13);
Node node3 = new Node(11);
Node node4 = new Node(10);
Node node5 = new Node(1);
node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
node2.random = node1;
node3.random = node5;
node4.random = node3;
node5.random = node1;
Node node = copyRandomList(node1);
System.out.println(node);
}
public Node copyRandomList(Node head) {
Node index = head;
while (index != null) {
Node tmp = index.next;
index.next = new Node(index.val);
index.next.next = tmp;
index = index.next.next;
}
index = head;
while (index != null) {
if (index.random != null) {
index.next.random = index.random.next;
}
index = index.next.next;
}
Node newHead = head.next;
index = newHead;
Node tmpPreIndex = head;
while (index.next != null) {
tmpPreIndex.next = tmpPreIndex.next.next;
tmpPreIndex = tmpPreIndex.next;
index.next = index.next.next;
index = index.next;
}
tmpPreIndex.next = null;
return newHead;
}
}

View File

@ -0,0 +1,53 @@
package cn.whaifree.test;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class Proxy {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Rent.class);
enhancer.setCallback(new Agency());
Rent o = (Rent) enhancer.create();
System.out.println("起始的钱:" + o.money);
o.rent();
System.out.println("剩下的钱:" + o.money);
}
static class Rent{
int money = 100;
void rent() {
System.out.println("租房!");
}
}
static class Agency implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
Rent o1 = (Rent) o;
o1.money -= 20;
System.out.println("扣费20为中介费");
return methodProxy.invokeSuper(o, objects);
//https://blog.csdn.net/z69183787/article/details/106878203
/**
* 调用invoke实际是调用cglib生成的子类的方法
* 这个子类
* method{
* interceptor(obj.method)
* }
* 正确使用
* 将obj从其他地方传进来
*
*
* 调用invokeSuper实际是调用父类的方法method
*/
}
}
}

View File

@ -1,11 +1,15 @@
package cn.whaifree.test;
import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class TestCacheThreadPool {
@ -25,6 +29,17 @@ public class TestCacheThreadPool {
System.out.println("\n");
}
ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>();
map.put("1", "233");
String compute = map.compute("1", (k, v) -> {
return k + v;
});
String merge = map.merge("1", "233", (k, v) -> {
return k + v; // 没有就value有就+value
});
System.out.println(merge);
System.out.println(compute);
// ExecutorService executorService = Executors.newCachedThreadPool();
// for (int i = 0; i < 10; i++) {
// int finalI = i;
@ -45,4 +60,216 @@ public class TestCacheThreadPool {
}
}
@Test
public void single() {
for (int i = 0; i < 100; i++) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " " + Single.getSingle());
}
}).start();
}
}
static class Single {
private static Single o = null;
public static Single getSingle() {
if (o == null) {
synchronized (Single.class) {
if (o == null) { // 防止第二个线程再创建一个
System.out.println("创建");
o = new Single();
}
}
}
return o;
}
}
static class Singleton {
// 不使用volatile关键字
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
public static void main(String[] args) {
// 创建多个线程尝试获取单例实例
for (int i = 0; i < 10; i++) {
new Thread(() -> {
for (int j = 0; j < 10; j++) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " 获取到的实例为: " + Singleton.getInstance());
}
}).start();
}
System.out.println("-======");
}).start();
}
}
}
static class MultiConditionDemo {
private final ReentrantLock lock = new ReentrantLock();
private final Condition condition1 = lock.newCondition();
private final Condition condition2 = lock.newCondition();
private String message = "等待消息";
public static void main(String[] args) {
MultiConditionDemo demo = new MultiConditionDemo();
new Thread(() -> demo.producer()).start();
new Thread(() -> demo.consumer()).start();
}
public void producer() {
lock.lock();
try {
while ("等待消息".equals(message)) {
condition1.await(); // 等待条件1
}
message = "这是生产者发送的消息";
System.out.println("生产者发送消息:" + message);
condition2.signal(); // 通知条件2上的等待线程
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void consumer() {
lock.lock();
try {
while (!"这是生产者发送的消息".equals(message)) {
condition2.await(); // 等待条件2
}
System.out.println("消费者接收到的消息:" + message);
message = "等待消息";
condition1.signal(); // 通知条件1上的等待线程
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
static class reentrantLockDemo {
static ReentrantLock lock = new ReentrantLock();
static int num = 0;
static Condition condition = lock.newCondition();
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
lock.lock();
while (num % 2 == 0) {
try {
condition.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println("A");
num++;
condition.signalAll();
lock.unlock();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
lock.lock();
while (num % 2 != 0) {
try {
condition.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println("B");
num++;
condition.signalAll();
lock.unlock();
}
}
}).start();
}
}
static class synDemo {
static Object lock = new Object();
// static Condition condition = lock.newCondition();
static int num = 0;
public static void main(String[] args) throws InterruptedException {
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
synchronized (lock) {
while (num % 2 == 0) {
try {
lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println("A");
num++;
lock.notify();
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
synchronized (lock) {
while (num % 2 == 1) {
try {
lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println("B");
num++;
lock.notify();
}
}
}
}).start();
}
}
}