并发编程3

本文介绍了Java 1.7引入的ForkJoin框架,这是一种用于并行处理的高级线程池技术,通过任务拆分和工作窃取提升效率。ForkJoinTask和ForkJoinPool是其核心组件,前者用于定义任务,后者作为线程池执行任务。此外,文章还探讨了Volatile关键字的作用,强调了它的可见性和轻量级同步特性,确保多线程环境中的数据一致性。
摘要由CSDN通过智能技术生成

ForkJoin框架
ForkJoin是jdk1.7后发布的多线程并发处理框架,功能上和JUC类似,JUC更多的时候是使用单个类完成操作,ForkJoin使用多个类完成某项工作,处理上比juc更加丰富,实际开发中使用的场景并不是很多,互联网公司真正有高并发需求的时候才会使用,面试的时候会加分
它的本质上是对线程池的一种补充,对线程池的一种扩展,基于线程池的,它的核心思想就是将一个大型的任务拆分成很多个小任务,分别执行,最终将小任务的结果进行汇总,生成最终结果
在这里插入图片描述
本质上就是把一个线程的任务拆分成多个小任务,然后由多个线程并发执行,最终将结果进行汇总

比如A,B两个线程同时再执行,A的任务比较多,B的任务相对较少,B先执行完毕,这时候B去帮助A完成任务(将A的一部分任务拿过来替A执行,执行完毕之后再把结果进行汇总),从而提高效率,这也叫做工作窃取
在这里插入图片描述
ForkJoin框架,核心就两个类

  • ForkJoinTask(描述任务)
  • ForkJoinPool(线程池) 提供多线程并发工作窃取
    使用forkjoinTask最重要的就是搞清楚如何拆分任务,这里用的是递归思想
    1.需要创建一个ForkJoinTask任务,ForkJoinTask是一个抽象类,不能直接创建ForkJoinTask的实例化对象,开发者需要自定义一个类,继承ForkJoinTask的子类RecursiveTask,Recursive就是递归的意思,该类就提供了实现递归的功能
    在这里插入图片描述
/**
 * 10亿求和
 */
public class ForkJoinDemo extends RecursiveTask<Long> {
        private Long start;  // 开始数
        private Long end;  // 起始数
        private Long temp  = 100_0000L; // 临界值
    public ForkJoinDemo(Long start, Long end) {
        this.start = start;
        this.end = end;
    }
    @Override
    protected Long compute() {
         if ((end-start)<temp){
             Long sum = 0L;
             for (Long i = start; i <=end ; i++) {
                 sum+=i;
             }
               return sum;
         }else {
               Long avg = (start+end)/2;
             ForkJoinDemo task1 = new ForkJoinDemo(start, avg);
                 task1.fork();
             ForkJoinDemo task2 = new ForkJoinDemo(avg, end);
                  task2.fork();
                  return task1.join()+task2.join();
         }  
    }
}

测试代码

public  class Test {
    public static void main(String[] args) {

        long startTime = System.currentTimeMillis();
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        ForkJoinTask<Long> task = new ForkJoinDemo(0L, 10_0000_0000L);
                   // 执行
              forkJoinPool.execute(task);
               Long sum = 0L;
        try {
            sum = task.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
             // 结束时间
        long end = System.currentTimeMillis();
        System.out.println(sum+"共耗时"+(end-startTime));
    }
}

Volatile关键字
在这里插入图片描述
Volatile是jvm提供的轻量级同步机制,可见性,设置对主内存对线程可见

public class Test {
  private static volatile int num = 0;
  public static void main(String[] args) {
      /**
       * 循环
       */
       new Thread(()->{
           while (num==0){

           }
       }).start();
      try {
          TimeUnit.SECONDS.sleep(1);
      } catch (InterruptedException e) {
          e.printStackTrace();
      }
            num = 1;
        System.out.println(num);
  }
}

一个线程执行完任务之后,会把变量还回到主内存中,并且从主内存中读取到当前最新的值,如果是一个空的任务,则不会重新读取主内存中的值

public class Test {

    private static  int num = 0;
    public static void main(String[] args) {
        /**
         * 循环
         */
         new Thread(()->{
             while (num==0){
                 System.out.println("Thread====>再执行");
             }
         }).start();
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
              num = 1;
          System.out.println(num);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值