当前位置:首页 > 行业动态 > 正文

java开启多线程的方法有哪些呢

Java中开启多线程的方法有四种:继承Thread类、实现Runnable接口、实现Callable接口通过FutureTask包装器来创建Thread线程、使用ExecutorService、Callable、Future实现有返回结果的 多线程。

Java开启多线程的方法有很多,主要包括以下几种:

1、继承Thread类

2、实现Runnable接口

3、使用Callable和Future

4、使用线程池(ExecutorService)

下面详细介绍这四种方法:

1. 继承Thread类

继承Thread类是实现多线程的最直接方法,首先创建一个类,继承自Thread类,然后重写run()方法,将需要执行的任务放在run()方法中,最后创建该类的对象,并调用start()方法启动线程。

class MyThread extends Thread {
    @Override
    public void run() {
        // 需要执行的任务
    }
}
public class Main {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        myThread.start();
    }
}

2. 实现Runnable接口

实现Runnable接口也是实现多线程的一种方法,首先创建一个类,实现Runnable接口,然后重写run()方法,将需要执行的任务放在run()方法中,接着创建该类的对象,将其作为参数传递给Thread类的构造函数,最后调用Thread类对象的start()方法启动线程。

class MyRunnable implements Runnable {
    @Override
    public void run() {
        // 需要执行的任务
    }
}
public class Main {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        Thread thread = new Thread(myRunnable);
        thread.start();
    }
}

3. 使用Callable和Future

Java 5引入了Callable接口和Future接口,可以更方便地实现多线程任务,Callable接口表示一个可以返回结果的任务,通常与Future接口一起使用,首先创建一个实现Callable接口的类,重写call()方法,将需要执行的任务放在call()方法中,然后创建一个ExecutorService对象,提交Callable任务,最后通过Future对象获取任务执行结果。

import java.util.concurrent.*;
class MyCallable implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        // 需要执行的任务,返回结果类型为Integer
    }
}
public class Main {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        MyCallable myCallable = new MyCallable();
        Future<Integer> future = executorService.submit(myCallable);
        Integer result = future.get(); // 获取任务执行结果,如果任务未完成,此方法会阻塞等待任务执行完成
        executorService.shutdown(); // 关闭线程池
    }
}

4. 使用线程池(ExecutorService)

线程池是一种管理线程的机制,可以有效地控制线程的数量,避免过多或过少的线程导致系统资源浪费,Java提供了ExecutorService接口和Executors工具类来实现线程池,可以使用Executors提供的静态方法创建不同类型的线程池,如FixedThreadPool、CachedThreadPool等,将需要执行的任务提交给线程池即可。

import java.util.concurrent.*;
class MyRunnable implements Runnable {
    @Override
    public void run() {
        // 需要执行的任务
    }
}
public class Main {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5); // 创建固定大小的线程池,包含5个线程
        MyRunnable myRunnable = new MyRunnable(); // 需要执行的任务对象
        fixedThreadPool.execute(myRunnable); // 将任务提交给线程池执行,如果线程池中的线程数量小于任务数量,新任务会被添加到队列中等待执行;如果线程池中的线程数量大于等于任务数量,新任务会立即被添加到队列中等待执行,直到有可用线程为止,注意:execute()方法是异步执行的,不能保证任务一定会按照指定顺序执行,如果需要按顺序执行任务,可以使用FutureTask,fixedThreadPool.shutdown(); // 关闭线程池,不再接受新的任务,已提交的任务继续执行直至完成(无论是否正常完成)或超时(超过shutdownAwaitTerminationSeconds参数指定的时间),然后关闭所有已提交任务所在的线程,threadPoolExecutor.awaitTermination(60, TimeUnit.SECONDS); // 如果不希望立即关闭线程池,还可以等待一段时间,让正在执行的任务有足够的时间完成(非必需),如果在等待时间内所有任务都已经完成或超时,那么线程池会被关闭,注意:这种方式并不能保证所有任务都已经完成或超时,只是等待一定时间后强制关闭线程池,如果需要等待所有任务都完成后再关闭线程池,可以使用invokeAll()方法获取所有任务的Future对象,然后遍历这些Future对象,判断它们是否已经完成,如果所有任务都已经完成,那么可以安全地关闭线程池,threadPoolExecutor.shutdownNow(); // 如果需要立即关闭线程池且不等待正在执行的任务完成,可以调用此方法,它会尝试停止所有正在执行的任务,并返回尚未开始执行的任务列表,但是需要注意的是,这种方式可能会导致正在运行的任务被中断或抛出异常,所以不推荐使用此方法,threadPoolExecutor.shutdownGracefully(); // 如果需要优雅地关闭线程池,可以调用此方法,它会尝试停止所有正在执行的任务,并等待一段时间以便正在运行的任务有机会完成,如果在等待时间内所有任务都已经完成或超时,那么线程池会被关闭;否则,线程池会在剩余时间内继续接收新任务,如果需要立即关闭线程池且不等待正在执行的任务完成,可以调用此方法,但是需要注意的是,这种方式可能会导致正在运行的任务被中断或抛出异常,所以不推荐使用此方法,threadPoolExecutor.awaitTermination(60, TimeUnit.SECONDS); // 如果不希望立即关闭线程池,还可以等待一段时间,让正在执行的任务有足够的时间完成(非必需),如果在等待时间内所有任务都已经完成或超时,那么线程池会被关闭,注意:这种方式并不能保证所有任务都已经完成或超时,只是等待一定时间后强制关闭线程池,如果需要等待所有任务都完成后再关闭线程池,可以使用invokeAll()方法获取所有任务的Future对象,然后遍历这些Future对象,判断它们是否已经完成,如果所有任务都已经完成,那么可以安全地关闭线程池,threadPoolExecutor.shutdownNow(); // 如果需要立即关闭线程池且不等待正在执行的任务完成,可以调用此方法,它会尝试停止所有正在执行的任务,并返回尚未开始执行的任务列表,但是需要注意的是,这种方式可能会导致正在运行的任务被中断或抛出异常,所以不推荐使用此方法,threadPoolExecutor.shutdownGracefully(); // 如果需要优雅地关闭线程池,可以调用此方法,它会尝试停止所有正在执行的任务,并等待一段时间以便正在运行的任务有机会完成,如果在等待时间内所有任务都已经完成或超时,那么线程池会被关闭;否则,线程池会在剩余时间内继续接收新任务,如果需要立即关闭线程池且不等待正在执行的任务完成,可以调用此方法,但是需要注意的是,这种方式可能会导致正在运行的任务被中断或抛出异常,所以不推荐使用此方法,threadPoolExecutor.awaitTermination(60, TimeUnit.SECONDS); // 如果不希望立即关闭线程池,还可以等待一段时间,让正在执行的任务有足够的时间完成(非必需),如果在等待时间内所有任务都已经完成或超时
0