如何在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类似,但允许线程执行后返回结果,且可抛出受检异常。需结合Future或FutureTask获取结果。

代码语言:java复制import java.util.concurrent.Callable;

import java.util.concurrent.ExecutionException;

import java.util.concurrent.FutureTask;

// 1. 实现Callable接口,指定返回值类型(此处为Integer)

class MyCallable implements Callable {

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 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)

}

}总结简单场景:用Thread或Runnable(推荐Runnable)。需要返回值:用Callable + Future。高效管理线程:用线程池。多线程共享资源:需考虑线程安全(synchronized或Lock)。多线程编程的核心是并发协作与资源同步,实际开发中需根据场景选择合适的实现方式。

Copyright © 2088 2008世界杯_2026世界杯举办地 - mwllb.com All Rights Reserved.
友情链接