首页 > 其他分享 >单机线程池执行断电了应该怎么处理?Fork/Join框架是什么?

单机线程池执行断电了应该怎么处理?Fork/Join框架是什么?

时间:2023-11-03 12:31:54浏览次数:30  
标签:Fork Join 队列 任务 线程 窃取

单机线程池执行断电了应该怎么处理?

我们可以对正在处理和阻塞队列的任务做事务管理或者对阻塞队列中的任务持久化处理,并且当断电或者系统崩溃,操作无法继续下去的时候,可以通过回溯日志的方式来撤销正在处理的已经执行成功的操作。然后重新执行整个阻塞队列。

也就是说,对阻塞队列持久化;正在处理任务事务控制;断电之后正在处理任务的回滚,通过日志恢复该次操作;服务器重启后阻塞队列中的数据再加载。

Fork/Join框架

Fork/Join框架是Java7提供的一个用于并行执行任务的框架,是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架。

要想掌握Fork/Join框架,首先需要理解两个点,分而治之和工作窃取算法。

分而治之

Fork/Join框架的定义,其实就体现了分治思想:将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解。

单机线程池执行断电了应该怎么处理?Fork/Join框架是什么?_阻塞队列

工作窃取算法

大任务拆成了若干个小任务,把这些小任务放到不同的队列里,各自创建单独线程来执行队列里的任务。

那么问题来了,有的线程干活块,有的线程干活慢。干完活的线程不能让它空下来,得让它去帮没干完活的线程干活。它去其它线程的队列里窃取一个任务来执行,这就是所谓的工作窃取。

工作窃取发生的时候,它们会访问同一个队列,为了减少窃取任务线程和被窃取任务线程之间的竞争,通常任务会使用双端队列,被窃取任务线程永远从双端队列的头部拿,而窃取任务的线程永远从双端队列的尾部拿任务执行。

单机线程池执行断电了应该怎么处理?Fork/Join框架是什么?_阻塞队列_02

看一个Fork/Join框架应用的例子,计算1~n之间的和:1+2+3+…+n

设置一个分割阈值,任务大于阈值就拆分任务

任务有结果,所以需要继承RecursiveTask

public class CountTask extends RecursiveTask<Integer> {
    private static final int THRESHOLD = 16; // 阈值
    private int start;
    private int end;
    public CountTask(int start, int end) {
        this.start = start;
        this.end = end;
    }
    @Override
    protected Integer compute() {
        int sum = 0;
        // 如果任务足够小就计算任务
        boolean canCompute = (end - start) <= THRESHOLD;
        if (canCompute) {
          for (int i = start; i <= end; i++) {
          sum += i;
        	}
        } else {
          // 如果任务大于阈值,就分裂成两个子任务计算
          int middle = (start + end) / 2;
          CountTask leftTask = new CountTask(start,middle);
          CountTask rightTask = new CountTask(middle + 1, end);
          // 执行子任务
          leftTask.fork();
          rightTask.fork(); // 等待子任务执行完,并得到其结果
          int leftResult = leftTask.join();
          int rightResult = rightTask.join(); // 合并子任务
          sum = leftResult + rightResult;
        }
        return sum;
        }
        public static void main(String[] args) {
          ForkJoinPool forkJoinPool = new ForkJoinPool(); // 生
          成一个计算任务,负责计算1+2+3+4
          CountTask task = new CountTask(1, 100); // 执行一个任务
          Future<Integer> result = forkJoinPool.submit(task);
          try {
            System.out.println(result.get());
            } catch (InterruptedException e) {
            } catch (ExecutionException e) {
          }
    }
}

ForkJoinTask与一般Task的主要区别在于它需要实现compute方法,在这个方法里,首先需要判断任务是否足够小,如果足够小就直接执行任务。如果比较大,就必须分割成两个子任务,每个子任务在调用fork方法时,又会进compute方法,看看当前子任务是否需要继续分割成子任务,如果不需要继续分割,则执行当前子任务并返回结果。使用join方法会等待子任务执行完并得到其结果。

标签:Fork,Join,队列,任务,线程,窃取
From: https://blog.51cto.com/u_16269508/8164054

相关文章

  • java网络编程与多线程
      一、Java 网络编程网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来。java.net包中J2SE的API包含有类和接口,它们提供低层次的通信细节。你可以直接使用这些类和接口,来专注于解决问题,而不用关注通信细节。java.net包中提供了两种常见的网络......
  • 将GitHub上的forked仓库删除
    内容来自DOChttps://q.houxu6.top/?s=将GitHub上的forked仓库删除我开始使用git和GitHub,有一个项目我正在GitHub上关注。我不小心点击了fork它。现在它似乎成了一个新的项目。我对这件事有一些疑问:我知道如果我对我的forked仓库进行提交或其他操作,它将会被更新,但是更新后......
  • JAVA多线程之线程间的通信方式
    一,介绍本总结我对于JAVA多线程中线程之间的通信方式的理解,主要以代码结合文字的方式来讨论线程间的通信,故摘抄了书中的一些示例代码。 二,线程间的通信方式①同步这里讲的同步是指多个线程通过synchronized关键字这种方式来实现线程间的通信。参考示例:publicclassMyObj......
  • 11月1日线程锁
    目录线程锁下面用进程锁解决这个问题修改比喻线程锁为什么会有线程锁,首先这里说一个例子假设我的计算机的CPU略微拉跨一点,然后我有个三个线程进行计算,同时计算量都不小,这时候就有可能出现算错的情况具体代码如下fromthreadingimportThreadx=0deftask():globa......
  • 线程安全
    线程安全:https://www.cnblogs.com/lixinjie/p/a-answer-about-thread-safety-in-a-interview.html什么是线程安全和线程不安全 首先要明白线程的工作原理,jvm有一个main  memory,而每个线程有自己的working  memory,一个线程对一个variable进行操作时,都要在自己的working......
  • JUC并发编程学习笔记(一)认知进程和线程
    进程和线程进程一个程序,如QQ.exe,是程序的集合一个进程往往可以包含多个线程,至少包含一个java默认有两个线程,GC垃圾回收线程和Main线程线程:一个进程中的各个功能java无法真正的开启线程,因为java是运行在虚拟机上的,所以只能通过C++,通过native本地方法调用C++开启线程priva......
  • 定时任务@Scheduled之单线程多线程问题
    现象在一个类内,写了两个定时任务,发现它们竟然是串行执行的。于是想到,@Scheduled该不会是单线程执行折吧?于是找了一下,发现还真的是。。。可参考:https://blog.csdn.net/Mr_EvanChen/article/details/103408290解决方案1、ScheduledTaskRegistrar有一个setScheduler()方......
  • mysql,左连接 ,查询右表为null的写法,删除,带join条件的写法
    select*fromsale_guestsgleftjoinsale_billsbonsg.bill_id=sb.idwheresg.gmt_create>'2023-10-20'andsb.bill_noisNULLselect*fromsale_empseleftjoinsale_billsbonse.bill_id=sb.idwherese.gmt_create>'2023-10-20'and......
  • 终于有人把进程与线程讲清楚了
    前言很多人对进程、线程没有什么概念,面试的时候也说不出其中的核心内涵。所以,今天我打算花点篇幅把进程和线程讲清楚。01CPU与内存**CPU**大家都知道是计算机的中央运算单元,用来计算的。CPU从内存里面读取一条一条的代码指令,然后根据指令来执行运算(加,减,乘,除,复制数据等)。......
  • C 语言多线程基础
    ......