java学习——guava并发编程练习

发布于:2025-07-07 ⋅ 阅读:(17) ⋅ 点赞:(0)

一直学习理论怎么能不做练习呢?下面我将出几个编程题来巩固编程。

练习1:

新建三个线程,使用并发编程,同时计算三个线程的数并且输出计算的过程,线程1计算从1加到100,线程2计算50的阶乘,线程三计算根号三并且输出小数点后十位。

答案

import com.google.common.util.concurrent.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class MultiThreadCalculator {
   
    // 创建监听线程池
    private static final ListeningExecutorService executor = 
        MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(3));
    
    public static void main(String[] args) {
   
        // 启动三个计算任务
        ListenableFuture<?> additionFuture = executor.submit(new AdditionTask());
        ListenableFuture<?> multiplicationFuture = executor.submit(new MultiplicationTask());
        ListenableFuture<?> sqrtFuture = executor.submit(new SquareRootTask());
        
        // 添加回调处理异常
        Futures.addCallback(additionFuture, new LoggingCallback(), executor);
        Futures.addCallback(multiplicationFuture, new LoggingCallback(), executor);
        Futures.addCallback(sqrtFuture, new LoggingCallback(), executor);
        
        // 等待所有任务完成
        ListenableFuture<?> allFutures = Futures.allAsList(
            additionFuture, multiplicationFuture, sqrtFuture
        );
        
        try {
   
            allFutures.get();
            System.out.println("\n所有计算任务完成!");
        } catch (Exception e) {
   
            e.printStackTrace();
        } finally {
   
            executor.shutdown();
        }
    }
    
    // 加法任务:计算1加到100
    static class AdditionTask implements Runnable {
   
        @Override
        public void run() {
   
            int sum = 0;
            for (int i = 1; i <= 100; i++) {
   
                sum += i;
                System.out.println("[加法线程] 添加 " + i + " → 当前总和: " + sum);
                Uninterruptibles.sleepUninterruptibly(50, TimeUnit.MILLISECONDS);
            }
            System.out.println("\n[加法线程] 最终结果: 1到100的和 = " + sum);
        }
    }
    
    // 乘法任务:计算2乘到50(使用BigInteger避免溢出)
    static class MultiplicationTask implements Runnable {
   
        @Override
        public void run() {
   
            BigInteger product = BigInteger.ONE;
            for (int i = 2; i <= 50; i++) {
   
                product = product.multiply(BigInteger.valueOf(i));
                System.out.println("[乘法线程] 乘以 " + i + " → 当前乘积: " + product);
                Uninterruptibles.sleepUninterruptibly(70, TimeUnit.MILLISECONDS);
            }
            System.out.println("\n[乘法线程] 最终结果: 2到50的乘积 = " + product);
        }
    }
    
    // 开方任务:计算√3的小数点后10位数字
    static class SquareRootTask implements Runnable {
   
        @Override
        public void run() {
   
            // 计算√3到小数点后20位精度
            BigDecimal sqrt3 = BigDecimal.valueOf(3).sqrt(new MathContext(20));
            String decimalPart = sqrt3.toString().split("\\.")[1];
            
            System.out.println("[开方线程] √3 完整值: " + sqrt3);
            
            // 输出小数点后10位数字
            for (int i = 0; i < 10; i++) {
   
                if (i < decimalPart.length()) {
   
                    char digit = decimalPart.charAt(i);
                    System.out.println("[开方线程] 小数点后第" + (i+1) + "位: " + digit);
                } else {
   
                    System.out.println("[开方线程] 小数点后第" + (i+1) + "位: 0");
                }
                Uninterruptibles.sleepUninterruptibly(100, TimeUnit.MILLISECONDS);
            }
            
            // 只输出前10位小数
            String result = decimalPart.length() >= 10 ? decimalPart.substring(0, 10) : decimalPart;
            System.out.println("\n[开方线程] 最终结果: √3 ≈ " + result);
        }
    }
    
    // 通用回调处理
    static class LoggingCallback implements FutureCallback<Object> {
   
        @Override
        public void onSuccess(Object result) {
   
            // 任务成功完成,无需特别处理
        }
        
        @Override
        public void onFailure(Throwable t) {
   
            System.err.println("任务失败: " + t.getMessage());
            t.printStackTrace();
        }
    }
}

练习2

和练习1一样,对线程的执行顺序有要求,要求线程1执行一半时执行线程2,线程2执行一半时执行线程3,等待线程3执行完毕后再执行线程2,线程2执行完毕后执行线程1,要求分清不同线程的执行过程

答案:

package org.example;

import com.google.common.util.concurrent.*;

import java.math.BigDecimal;

网站公告

今日签到

点亮在社区的每一天
去签到