java线程池-ForkJoinPool使用小记

特点

ForkJoinPool是Java中的一个特殊的线程池,用于执行可以分解为更小部分的任务,并且这些部分可以并行执行,特点是用来执行分治任务。思想是将大任务分解为小任务,然后继续将小任务分解,直至能够直接解决为止,然后再依次将任务的结果合并。

工作机制

ForkJoinPool采取工作窃取算法,以避免工作线程由于拆分了任务之后的join等待过程。这样处于空闲的工作线程将从其他工作线程的队列中主动去窃取任务来执行。(从其它队列尾部窃取任务,有兴趣的同学可以自行去查阅资料)

使用

1.例1

ForkJoinPool pool = new ForkJoinPool(3);
        pool.submit(() -> {
            // 业务
        }).join();
        pool.shutdown();

创建一个并行级别为3的线程池,提交任务,join等待任务完成,最后再关闭销毁资源。

2.例2

QwMarkForkJoinPool pool = new QwMarkForkJoinPool(3);
        List<Integer> elements = Lists.newArrayList();
        for (int i = 1; i <= 1000; i++) {
            elements.add(i);
        }
        pool.submit(() -> elements.parallelStream().forEach(ele -> {
         System.out.println(ele);
        })).join();
       pool.shutdown();
public class QwMarkForkJoinPool extends ForkJoinPool {

    public QwMarkForkJoinPool(int poolSize) {
        super(poolSize, QwMarkForkJoinWorkerThread::new,null,false);
    }
}
public class QwMarkForkJoinWorkerThread extends ForkJoinWorkerThread {
    /**
     * Creates a ForkJoinWorkerThread operating in the given pool.
     *
     * @param pool the pool this thread works in
     * @throws NullPointerException if pool is null
     */
    protected QwMarkForkJoinWorkerThread(ForkJoinPool pool) {
        super(pool);
        setName("qwMarkThread-" + getId());
    }
}

自定义线程池名称

3.例3

@Component
public class BizManager {
 
    private QwMarkForkJoinPool pool;

    @PostConstruct
    public void init(){
        pool = new QwMarkForkJoinPool(3);
    }

    public void bizMethod(){
        pool.submit(() ->  
            // 业务
        })).join();
    }
 }

接入到spring

Mark

每次submit任务后,都会创建新的work线程,至于线程什么时候会被销毁。销毁主要发生在整个线程池关闭且所有任务都执行完毕之后。核心线程会一直保持活跃直到线程池关闭,而非核心线程则会在空闲一段时间后销毁。目前还不清楚怎么设置核心线程数。

Protobuf是一种高效的序列化协议,可以用于数据交换和数据存储。它的主要优势是大小小,速度快,可扩展性强。下面是使用Protobuf的一些小记: 1. 定义消息格式 首先,需要定义消息格式,以便Protobuf可以将数据序列化和反序列化。消息格式定义在.proto文件中,使用protobuf语言编写。例如,下面是一个简单的消息格式定义: ``` syntax = "proto3"; message Person { string name = 1; int32 age = 2; } ``` 这个消息格式定义了一个名为Person的消息,包含两个字段:name和age。 2. 生成代码 一旦消息格式定义好,就可以使用Protobuf编译器生成代码。编译器将根据消息格式定义生成相应的代码,包括消息类、序列化和反序列化方法等。可以使用以下命令生成代码: ``` protoc --java_out=. message.proto ``` 这将生成一个名为message.pb.javaJava类,该类包含Person消息的定义以及相关方法。 3. 序列化和反序列化 一旦生成了代码,就可以使用Protobuf序列化和反序列化数据。例如,下面是一个示例代码,将一个Person对象序列化为字节数组,并将其反序列化为另一个Person对象: ``` Person person = Person.newBuilder() .setName("Alice") .setAge(25) .build(); byte[] bytes = person.toByteArray(); Person deserializedPerson = Person.parseFrom(bytes); ``` 这个示例代码创建了一个Person对象,将其序列化为字节数组,然后将其反序列化为另一个Person对象。在这个过程中,Protobuf使用生成的代码执行序列化和反序列化操作。 以上是使用Protobuf的一些基本步骤和注意事项,希望对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值