当前位置: 首页 > article >正文

JUC高并发编程6:Callable接口

1 创建线程的方式

在 Java 中,创建线程的方式主要有以下几种:

  1. 继承 Thread

    • 通过继承 Thread 类并重写 run() 方法来创建线程。
    • 示例代码:
      class MyThread extends Thread {
          @Override
          public void run() {
              // 线程执行的代码
          }
      }
      
      public class Main {
          public static void main(String[] args) {
              MyThread thread = new MyThread();
              thread.start();
          }
      }
      
  2. 实现 Runnable 接口

    • 通过实现 Runnable 接口并实现 run() 方法来创建线程。
    • 示例代码:
      class MyRunnable implements Runnable {
          @Override
          public void run() {
              // 线程执行的代码
          }
      }
      
      public class Main {
          public static void main(String[] args) {
              MyRunnable runnable = new MyRunnable();
              Thread thread = new Thread(runnable);
              thread.start();
          }
      }
      
  3. 实现 Callable 接口

    • 通过实现 Callable 接口并实现 call() 方法来创建线程。Callable 接口允许线程返回一个结果,并且可以抛出异常。
    • 示例代码:
      import java.util.concurrent.Callable;
      import java.util.concurrent.ExecutionException;
      import java.util.concurrent.FutureTask;
      
      class MyCallable implements Callable<Integer> {
          @Override
          public Integer call() throws Exception {
              // 线程执行的代码
              return 42;
          }
      }
      
      public class Main {
          public static void main(String[] args) throws InterruptedException, ExecutionException {
              MyCallable callable = new MyCallable();
              FutureTask<Integer> futureTask = new FutureTask<>(callable);
              Thread thread = new Thread(futureTask);
              thread.start();
              System.out.println(futureTask.get()); // 获取线程执行结果
          }
      }
      
  4. 线程池方式

    • 通过使用 ExecutorService 线程池来管理线程的创建和执行。
    • 示例代码:
      import java.util.concurrent.ExecutorService;
      import java.util.concurrent.Executors;
      
      public class Main {
          public static void main(String[] args) {
              ExecutorService executorService = Executors.newFixedThreadPool(2);
              executorService.submit(new MyRunnable());
              executorService.shutdown();
          }
      }
      

2 Callable 接口

2.1 Runnable 接口和 Callable 接口的比较

  • 是否有返回值

    • Runnable 接口的 run() 方法没有返回值。
    • Callable 接口的 call() 方法有返回值,返回类型为泛型。
  • 是否抛出异常

    • Runnable 接口的 run() 方法不能抛出受检异常(checked exception)。
    • Callable 接口的 call() 方法可以抛出受检异常。
  • 实现方法名称不同

    • Runnable 接口的实现方法是 run()
    • Callable 接口的实现方法是 call()

2.2 FutureTask 概述和原理

2.2.1 概述

FutureTaskFuture 接口的一个实现类,用于表示一个异步计算任务。它可以将 CallableRunnable 任务包装成 FutureTask,并且可以通过 FutureTask 获取任务的执行结果。

2.2.2 原理

  • 状态管理FutureTask 内部维护了一个状态变量,用于表示任务的当前状态(如未启动、运行中、已完成、已取消等)。
  • 结果存储FutureTask 内部存储了任务的执行结果或异常。
  • 线程安全FutureTask 通过 ReentrantLockCondition 实现线程安全的等待和通知机制。

2.2.3 示例代码

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

class MyCallable implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        // 线程执行的代码
        return 42;
    }
}

public class Main {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        MyCallable callable = new MyCallable();
        FutureTask<Integer> futureTask = new FutureTask<>(callable);
        Thread thread = new Thread(futureTask);
        thread.start();
        System.out.println(futureTask.get()); // 获取线程执行结果
    }
}

3 总结

在 Java 中,创建线程的方式有多种,包括继承 Thread 类、实现 Runnable 接口、实现 Callable 接口和使用线程池。Callable 接口允许线程返回结果并抛出异常,而 FutureTaskFuture 接口的一个实现类,用于管理异步计算任务的状态和结果。通过合理使用这些机制,可以有效地管理和控制线程的执行。

4 思维导图

在这里插入图片描述

5 参考链接

【【尚硅谷】大厂必备技术之JUC并发编程】


http://www.kler.cn/news/339868.html

相关文章:

  • 海报设计模板免费的好用吗?活动海报排版技巧轻松get
  • class 004 选择 冒泡 插入排序
  • CNAI趋势下,打造一体化AI赋能平台
  • 浅学React和JSX
  • Redis 实现 查找附近的人 功能
  • 如何优化spotbugsXml.xml文件来方便debug的落地方案来了
  • 渗透测试---01docker镜像和容器指令合集
  • kubeadm部署k8s1.28.0主从集群(cri-dockerd)
  • 使用Android studio进行Unit Test中遇到的问题记录
  • 前端编程艺术(3)---JavaScript
  • 开源 Three.js 案例及入门教程
  • uni-app之旅-day03-搜索
  • Jenkins打包,发布,部署
  • 【Golang】语法基础——切片:灵活、高效的数据处理利器
  • 如何查看是否是ip转发?
  • 自动化测试selenium篇(一)
  • 数字通信中不同信道类型对通信系统性能影响matlab仿真分析,对比AWGN,BEC,BSC以及多径信道
  • JavaWeb 15.详解Servlet及其源码
  • HTTP 和 WebSocket
  • PHP爬虫:获取商品SKU详细信息的利器