首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >如何在Java中实现多线程编程

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

原创
作者头像
啦啦啦191
发布2025-10-29 14:59:59
发布2025-10-29 14:59:59
1820
举报
文章被收录于专栏:Java开发Java开发

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

一、继承Thread

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

代码语言:java
复制
// 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();
    }
}

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

代码语言:txt
复制
线程A:执行第0次
线程B:执行第0次
线程A:执行第1次
线程B:执行第1次
...

二、实现Runnable接口

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

代码语言: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获取结果。

代码语言:java
复制
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自定义)。

代码语言:java
复制
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解决线程安全)

代码语言:java
复制
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)。

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、继承Thread类
  • 二、实现Runnable接口
  • 三、实现Callable接口(带返回值)
  • 四、线程池(ExecutorService)
  • 五、线程常用方法
  • 六、线程安全问题
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档