如何在Java中实现多线程编程

简介: Java多线程编程有三种主要方式:继承Thread类、实现Runnable接口、实现Callable接口(结合Future获取结果),推荐使用Runnable避免单继承限制。通过线程池(如ExecutorService)可高效管理线程,提升性能。多线程共享资源时需注意线程安全,使用synchronized或Lock机制保证数据一致性。适用于并发执行、异步计算等场景。

在Java中实现多线程编程主要有三种核心方式:继承Thread实现Runnable接口实现Callable接口(结合Future。此外,还可以通过线程池(ExecutorService)更高效地管理线程。以下是详细实现方法及代码示例:

一、继承Thread

Thread类是Java线程的基础类,通过继承它并重写run()方法定义线程执行逻辑,调用start()方法启动线程(而非直接调用run())。

// 1. 继承Thread类
class MyThread extends Thread {
   
    // 2. 重写run()方法,定义线程执行逻辑
    @Override
    public void run() {
   
        for (int i = 0; i < 5; i++) {
   
            // Thread.currentThread().getName()获取当前线程名称
            System.out.println(Thread.currentThread().getName() + ":执行第" + i + "次");
            try {
   
                Thread.sleep(500); // 线程休眠500ms(模拟耗时操作)
            } catch (InterruptedException e) {
   
                e.printStackTrace();
            }
        }
    }
}

public class ThreadDemo {
   
    public static void main(String[] args) {
   
        // 3. 创建线程对象
        MyThread thread1 = new MyThread();
        MyThread thread2 = new MyThread();

        // 设置线程名称(可选)
        thread1.setName("线程A");
        thread2.setName("线程B");

        // 4. 启动线程(调用start(),而非run())
        thread1.start();
        thread2.start();
    }
}

输出(顺序可能不同,体现线程并发)

线程A:执行第0次
线程B:执行第0次
线程A:执行第1次
线程B:执行第1次
...

二、实现Runnable接口

Runnable是函数式接口(仅含run()方法),通过实现它定义线程逻辑,再将实例传入Thread类启动。推荐此方式,因为Java单继承,但可多实现。

// 1. 实现Runnable接口
class MyRunnable implements Runnable {
   
    // 2. 实现run()方法
    @Override
    public void run() {
   
        for (int i = 0; i < 5; i++) {
   
            System.out.println(Thread.currentThread().getName() + ":执行第" + i + "次");
            try {
   
                Thread.sleep(500);
            } catch (InterruptedException e) {
   
                e.printStackTrace();
            }
        }
    }
}

public class RunnableDemo {
   
    public static void main(String[] args) {
   
        // 3. 创建Runnable实例
        MyRunnable runnable = new MyRunnable();

        // 4. 将Runnable传入Thread,创建线程对象
        Thread thread1 = new Thread(runnable, "线程C");
        Thread thread2 = new Thread(runnable, "线程D");

        // 5. 启动线程
        thread1.start();
        thread2.start();
    }
}

特点:多个线程可共享同一个Runnable实例的资源(如成员变量),适合多线程协作。

三、实现Callable接口(带返回值)

Callable接口与Runnable类似,但允许线程执行后返回结果,且可抛出受检异常。需结合FutureFutureTask获取结果。

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

// 1. 实现Callable接口,指定返回值类型(此处为Integer)
class MyCallable implements Callable<Integer> {
   
    private int num;

    public MyCallable(int num) {
   
        this.num = num;
    }

    // 2. 实现call()方法(有返回值)
    @Override
    public Integer call() throws Exception {
   
        int sum = 0;
        for (int i = 1; i <= num; i++) {
   
            sum += i;
        }
        System.out.println(Thread.currentThread().getName() + ":计算完成");
        return sum; // 返回结果
    }
}

public class CallableDemo {
   
    public static void main(String[] args) throws ExecutionException, InterruptedException {
   
        // 3. 创建Callable实例
        MyCallable callable = new MyCallable(100);

        // 4. 用FutureTask包装Callable(FutureTask实现了Future和Runnable)
        FutureTask<Integer> futureTask = new FutureTask<>(callable);

        // 5. 传入Thread启动
        Thread thread = new Thread(futureTask, "计算线程");
        thread.start();

        // 6. 调用get()获取结果(会阻塞当前线程,直到子线程执行完毕)
        int result = futureTask.get();
        System.out.println("1~100的和:" + result); // 输出:5050
    }
}

特点:适合需要线程返回结果的场景(如异步计算)。

四、线程池(ExecutorService

频繁创建/销毁线程会消耗资源,线程池可复用线程,提高效率。通过Executors工具类创建线程池(实际开发中推荐ThreadPoolExecutor自定义)。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadPoolDemo {
   
    public static void main(String[] args) {
   
        // 1. 创建固定大小的线程池(3个线程)
        ExecutorService executor = Executors.newFixedThreadPool(3);

        // 2. 提交任务(Runnable或Callable)
        for (int i = 0; i < 5; i++) {
   
            final int taskNum = i;
            executor.submit(new Runnable() {
   
                @Override
                public void run() {
   
                    System.out.println(Thread.currentThread().getName() + ":执行任务" + taskNum);
                    try {
   
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
   
                        e.printStackTrace();
                    }
                }
            });
        }

        // 3. 关闭线程池(不再接受新任务,等待现有任务完成)
        executor.shutdown();
    }
}

常用线程池类型

  • newFixedThreadPool(n):固定大小的线程池
  • newCachedThreadPool():可缓存的线程池(线程数动态调整)
  • newSingleThreadExecutor():单线程池(任务串行执行)
  • newScheduledThreadPool(n):支持定时/周期性任务的线程池

五、线程常用方法

方法 说明
start() 启动线程(底层调用run()
run() 线程执行逻辑(需重写)
sleep(long ms) 让当前线程休眠指定毫秒(不会释放锁)
join() 等待该线程执行完毕后,再继续执行其他线程
yield() 让出CPU资源,让其他线程优先执行
setPriority(int) 设置线程优先级(1~10,默认5)
isAlive() 判断线程是否存活

六、线程安全问题

多线程共享资源时可能出现数据不一致,需通过同步机制解决:

  • synchronized关键字(同步方法/代码块)
  • Lock接口(如ReentrantLock

示例(synchronized解决线程安全)

class Counter {
   
    private int count = 0;

    // 同步方法:保证同一时间只有一个线程执行
    public synchronized void increment() {
   
        count++;
    }

    public int getCount() {
   
        return count;
    }
}

public class ThreadSafety {
   
    public static void main(String[] args) throws InterruptedException {
   
        Counter counter = new Counter();
        Thread t1 = new Thread(() -> {
   
            for (int i = 0; i < 10000; i++) {
   
                counter.increment();
            }
        });
        Thread t2 = new Thread(() -> {
   
            for (int i = 0; i < 10000; i++) {
   
                counter.increment();
            }
        });

        t1.start();
        t2.start();
        t1.join(); // 等待t1完成
        t2.join(); // 等待t2完成

        System.out.println("最终计数:" + counter.getCount()); // 正确输出20000(无同步可能小于20000)
    }
}

总结

  • 简单场景:用ThreadRunnable(推荐Runnable)。
  • 需要返回值:用Callable + Future
  • 高效管理线程:用线程池。
  • 多线程共享资源:需考虑线程安全(synchronizedLock)。

多线程编程的核心是并发协作资源同步,实际开发中需根据场景选择合适的实现方式。

相关文章
|
14天前
|
存储 弹性计算 人工智能
【2025云栖精华内容】 打造持续领先,全球覆盖的澎湃算力底座——通用计算产品发布与行业实践专场回顾
2025年9月24日,阿里云弹性计算团队多位产品、技术专家及服务器团队技术专家共同在【2025云栖大会】现场带来了《通用计算产品发布与行业实践》的专场论坛,本论坛聚焦弹性计算多款通用算力产品发布。同时,ECS云服务器安全能力、资源售卖模式、计算AI助手等用户体验关键环节也宣布升级,让用云更简单、更智能。海尔三翼鸟云服务负责人刘建锋先生作为特邀嘉宾,莅临现场分享了关于阿里云ECS g9i推动AIoT平台的场景落地实践。
【2025云栖精华内容】 打造持续领先,全球覆盖的澎湃算力底座——通用计算产品发布与行业实践专场回顾
|
6天前
|
云安全 人工智能 安全
Dify平台集成阿里云AI安全护栏,构建AI Runtime安全防线
阿里云 AI 安全护栏加入Dify平台,打造可信赖的 AI
|
9天前
|
人工智能 运维 Java
Spring AI Alibaba Admin 开源!以数据为中心的 Agent 开发平台
Spring AI Alibaba Admin 正式发布!一站式实现 Prompt 管理、动态热更新、评测集构建、自动化评估与全链路可观测,助力企业高效构建可信赖的 AI Agent 应用。开源共建,现已上线!
850 25
|
8天前
|
机器学习/深度学习 人工智能 搜索推荐
万字长文深度解析最新Deep Research技术:前沿架构、核心技术与未来展望
近期发生了什么自 2025 年 2 月 OpenAI 正式发布Deep Research以来,深度研究/深度搜索(Deep Research / Deep Search)正在成为信息检索与知识工作的全新范式:系统以多步推理驱动大规模联网检索、跨源证据。
586 46
|
2天前
|
监控 BI 数据库
打工人救星!来看看这两家企业如何用Quick BI让业务更高效
Quick BI专业版监控告警助力企业高效运作,通过灵活配置规则与多渠道推送,让数据异常早发现、快响应,推动业务敏捷决策与持续增长。
打工人救星!来看看这两家企业如何用Quick BI让业务更高效
|
8天前
|
人工智能 Java Nacos
基于 Spring AI Alibaba + Nacos 的分布式 Multi-Agent 构建指南
本文将针对 Spring AI Alibaba + Nacos 的分布式多智能体构建方案展开介绍,同时结合 Demo 说明快速开发方法与实际效果。
567 44