Java并发编程:Kilim协程框架

一、介绍

Kilim是一个专为Java设计的轻量级协程框架,它通过字节码操纵技术实现了轻量级的协程,为Java开发者提供了更为灵活的并发编程选项。以下是关于Kilim协程框架的解析与应用:

1、Kilim协程框架解析

  • 协程(Coroutine)概念:协程是一种用户态的轻量级线程,它的执行可以在任何时候被挂起和恢复,由程序员控制其执行流程。协程的优势在于其轻量级和高效的上下文切换,可以大大降低并发编程的复杂度。
  • Kilim框架特性
    • 提供了超轻量级的线程和工具,支持快速、安全、零复制的消息传递。
    • 核心在于Mailbox跨线程共享内存,没有锁或同步,Mailbox支持多生产者,单消费者队列。
    • Actor协程场景存在大量的处理线程,都消耗在等待后端的处理,做异步化才有意义。
    • 类似于消息机制的方式,在守护线程和外部线程之间有一个队列(俗称信箱),外部线程只要把请求放入,守护线程就读取进行处理。
  • 核心组件
    • 任务载体(Task):Task对象是Kilim中核心的结构,所有业务的逻辑代码都是在Task中执行。
    • 任务调度器(Scheduler):Scheduler是Kilim框架中核心的任务调度器,负责管理任务的工作者线程WorkerThread,以及一个基本的FIFO队列,维护着Task任务列表。Scheduler负责分派Task给指定的工作者线程WorkerThread执行。
    • 任务上下文(Filber)
      在这里插入图片描述

2、Kilim协程框架应用

  • 网络通信:Kilim的协程模型非常适合处理大量的并发网络请求,例如Web服务器、代理服务器等。通过将网络请求封装为Task,使用Scheduler进行调度,可以实现高效的网络通信。
  • 高性能计算:对于需要大量计算资源的场景,如科学计算、大数据分析等,Kilim协程框架可以提供高效的并发处理能力。通过将计算任务拆分为多个Task,利用多核CPU并行处理,可以显著提高计算性能。
  • 异步编程:Kilim协程框架支持异步编程模型,使得开发者可以以更加直观和顺序的方式编写异步代码。通过将异步操作封装为Task,可以方便地实现异步回调、错误处理等功能。
  • 游戏开发:在游戏开发中,需要处理大量的并发事件和实时交互。Kilim协程框架可以提供高效的并发处理能力,使得开发者可以更加灵活地控制游戏逻辑的执行流程。

总之,Kilim协程框架为Java开发者提供了一种轻量级、高效的并发编程解决方案。通过利用协程的轻量级和高效的上下文切换特性,可以大大降低并发编程的复杂度,提高程序的性能和可维护性。

二、协程与线程性能对比

1、生产者和消费者案例

在这里插入图片描述

(1)Java多线程是吸纳

package chatpter11;

import java.util.ArrayList;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 创建了1000个生成者和1000个消费者,每个生产者生产10个产品,1000个消费者同时消费产品
 **/
public class TestThread {
    LinkedBlockingQueue<Integer> warehouse = new LinkedBlockingQueue<>(10);
    AtomicLong producerCount = new AtomicLong(0);   //生产次数计数
    AtomicLong consumerCount = new AtomicLong(0);   //消费次数计数

    private static final Integer FULL = 10; //最大生产数量

    public static void main(String[] args) {
        TestThread test = new TestThread();
        long startTime = System.currentTimeMillis();    //开始时间

        ArrayList<Thread> list = new ArrayList<>();
        for (int i = 0; i < 1000; i++) {    //创建1000个生产者线程
            Thread thread = new Thread(test.new Producer());
            thread.start();
            list.add(thread);
        }

        for (int i = 0; i < 1000; i++) {    //创建1000个消费者线程
            Thread thread = new Thread(test.new Consumer());
            thread.start();
            list.add(thread);
        }

        try {
            for (Thread thread : list) {
                //等待所有线程执行完
                thread.join();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("多线程执行时长: " + (System.currentTimeMillis() - startTime));
    }

    // 生产者(生产10个商品)
    class Producer implements Runnable {

        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                try {
                    warehouse.put(i);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                producerCount.incrementAndGet();
                System.out.println(Thread.currentThread().getName() + "生产者生产,目前总调用" + producerCount);
            }
        }
    }

    //消费者(消费10个商品)
    class Consumer implements Runnable {

        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                try {
                    warehouse.take();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                consumerCount.incrementAndGet();
                System.out.println(Thread.currentThread().getName() + "消费者消费,目前总调用" + consumerCount);
            }
        }
    }
}

多线程执行时长: 1447

(2)kilim协程框架实现

package chatpter11;

import kilim.Mailbox;
import kilim.Task;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 创建了1000个生成者和1000个消费者,每个生产者生产10个产品,1000个消费者同时消费产品
 * kilim协程实现
 **/
public class TestKilim {
    public static Map<Integer, Mailbox> mailMap = new HashMap<>();
    public static void main(String[] args) {
        //判断是否引入kilim
        if (kilim.tools.Kilim.trampoline(false, args)) {
            return;
        }

        Properties properties = new Properties();
        //设置4个工作线程
        properties.setProperty("kilim Scheduler.numThreads", "4");
        System.setProperties(properties);
        long startTime = System.currentTimeMillis();

        //todo 创建1000个生产者任务
        for (int i = 0; i < 1000; i++) {
            //相当于仓库,最大容量10
            Mailbox<Integer> mb = new Mailbox<>(1, 10);
            new ProducerTask(i, mb).start();
            //生产者把mailbox写入
            mailMap.put(i,mb);
        }

        for(int i = 0; i < 1000; i++) {
            //消费者把mailbox获取
            new ConsumerTask(mailMap.get(i)).start();
        }

        //开始运行
        Task.idledown();

        long endTime = System.currentTimeMillis();
        System.out.println("kilim总计花费时长: " + (endTime - startTime));
    }
}

consumer:

package chatpter11;

import kilim.Mailbox;
import kilim.Pausable;
import kilim.Task;

import java.util.concurrent.atomic.AtomicLong;

public class ConsumerTask extends Task<Object> {
    final static AtomicLong consumerCount = new AtomicLong();
    Mailbox<Integer> mb = null;
    public ConsumerTask(Mailbox<Integer> mb) {
        this.mb = mb;
    }

    public void execute() throws Pausable {
        Integer c = null;
        for (int i = 0; i < 10; i++) {
            c = mb.get();   //获取消息,阻塞协程线程(在mailbox为空时,消费者get会阻塞)
            consumerCount.incrementAndGet();
            System.out.println(Thread.currentThread().getName() + ":消费者,目前总调用" + consumerCount);
        }
    }
}

producer:

package chatpter11;

import kilim.Mailbox;
import kilim.Pausable;
import kilim.Task;

import java.util.concurrent.atomic.AtomicLong;

public class ProducerTask extends Task<Object> {
    final static AtomicLong producerCount = new AtomicLong();
    Integer count = null;
    Mailbox<Integer> mb = null;
    public ProducerTask(Integer count, Mailbox<Integer> mb) {
        this.count = count;
        this.mb = mb;
    }

    //相当于线程的run方法
    public void execute() throws Pausable {
        for(int i = 0; i < 10; i++) {
            mb.put(count);  //malbox满了,生产者put会阻塞
            producerCount.incrementAndGet();
            System.out.println(Thread.currentThread().getName() + ":生产者,目前总调用" + producerCount);
            count++;
        }
    }
}

运行结果:

kilim总计花费时长: 670
  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玉成226

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值