多线程应用案例

多线程应用案例

需求

解析一个Excel中多个sheet的数据,那么此时就可以考虑使用多线程,每个线程解析一个sheet中的数据,然后等待所有的sheet数据解析完成后,再把数据入库

在这个需求中,要实现主线程等待所有现场完成shee数据解析操作,

第一种方案:采用join()方法

public class MyJoinTest {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("开始解析数据");
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("解析sheet1 的数据");
            }
        });
        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("解析sheet2 的数据");
            }
        });
        thread1.start();
        thread2.start();
        thread1.join();
        thread2.join();
        System.out.println("入库");
        System.out.println("完成");
    }
}

执行结果:

www.zeeklog.com  - 多线程应用案例

看一下Thread的join方法

public final void join() throws InterruptedException {
    join(0);
}

www.zeeklog.com  - 多线程应用案例

死循环检查join线程是否活着,如果join线程活着则让当前线程永远等待,其中wait(0);表示永远等下去。直到join线程终止后,线程的this,notifyAll()方法会被调用,调用this.notifyAll方法是在JVM里面实现的。只有再JVM源码里能看见。

在JDK1.5后的并发包下提供了CountDownLatch也可以实现join的功能,并且比join的功能更多,

第二种方案:CountDownLatch

public class MyCountDownLatch {
    static CountDownLatch count = new CountDownLatch(2);
    public static void main(String[] args) throws InterruptedException {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("解析sheet1 的数据");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                count.countDown();
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("解析sheet2 的数据");
                try {
                    Thread.sleep(1500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                count.countDown();
            }
        }).start();
        count.await();
        System.out.println("入库");
        System.out.println("完成");
    }
}

执行结果

www.zeeklog.com  - 多线程应用案例

CountDownLatch的构造函数接收一个Int类型的参数作为计数器,如果你想等待n个点完菜,这里就传n。

当我们调用CountDownLatch的countDown()方法时候n就减1即就是n=n-1。CountDownLatch的await方法会阻塞当前线程,知道n=0,由于countDown()方法可以再任何地方使用,所以这里的n个点,可以是n个线程,也可以是一个线程里的n个执行步骤。用在多线程时,只需要把这个CountDownLatch的引用传递到线程里即可。

注:

计数器必须大于0,计数器等于0的时候,调用await方法是不会阻塞当前线程,CountDownLatch不可能重新初始化或者修改CountDownLatch对象的内部计数器的值,一个线程调用countDown方法happen-before,另外已发个线程调用await方法。

参考:《Java并发编程的艺术》

Read more

LibreChat 集成 Stripe 支付的奶妈级教程

LibreChat 集成 Stripe 支付的奶妈级教程

我们假设你已经熟悉基本的 React 和 Node.js 开发,并且正在使用 LibreChat 的默认技术栈(React 前端、Node.js 后端、Vite 构建工具,可能还有 Electron 桌面应用)。教程会特别考虑 Electron 环境下的适配问题(例如 macOS 中文路径或路由错误)。“奶妈级”带你从零开始实现支付功能(包括一次性支付和添加高级会员订阅) 教程目标 * 在 LibreChat 中添加支付页面,支持用户通过信用卡付款。 * 实现 Stripe 的一次性支付功能。 * (可选)扩展到订阅功能,管理高级会员状态。 * 解决 Electron 环境下的常见问题(如路由和路径解析)。 * 生成可公开推送的 Markdown 教程,方便社区参考。 前提条件 在开始之前,请确保你已准备好以下内容:

By Ne0inhk
超棒的雅思资源!

超棒的雅思资源!

雅思真题材料地址: https://github.com/zeeklog/IETLS 感谢所有人。材料来自:@shah0150 & @kbtxwer * 超棒的雅思资源 * 雅思简介 * 听力 * 阅读 * 写作 * 口语 * 词汇 * 其他 * YouTube 频道 * [播客] (#podcasts) 雅思简介 * 什么是雅思 - 了解什么是雅思 听力 * 高级听力 * 雅思官方网站 * 考试英语 * 英国广播公司节目 * 乔治梅森大学口音学习网站 - 学习不同的口音 * 英国广播公司播客 * 英国文化协会听力练习 阅读 * 雅思提升阅读 写作 * 雅思提升写作 * 雅思从 6 分到 9 分 * 迷你雅思 口语 * Verbling 提供在线英语家教服务

By Ne0inhk