深入浅出、玩转Java多线程( 二 )

  • 将需要执行的任务封装成一个Runnable或Callable对象,可以使用Java中的匿名内部类或Lambda表达式来创建 。
  • 将任务提交给ExecutorService对象执行,可以使用submit()方法提交Callable对象,或使用execute()方法提交Runnable对象 。
  • 在程序完成时,调用shutdown()方法关闭线程池,或使用awaitTermination()方法等待所有线程执行完毕 。
  • import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors; public class ExecutorDemo {public static void main(String[] args) {// 创建一个包含10个线程的线程池ExecutorService executor = Executors.newFixedThreadPool(10);// 提交10个任务给线程池执行for (int i = 0; i < 10; i++) {executor.execute(new MyTask(i));}// 关闭线程池executor.shutdown();}} class MyTask implements Runnable {private int id;public MyTask(int id) {this.id = id;}public void run() {System.out.println("Thread " + id + " is running");try {Thread.sleep(1000);// 模拟任务执行时间} catch (InterruptedException e) {e.printStackTrace();}}}在上面的例子中,先创建了一个ExecutorDemo类,在main函数中创建了一个包含10个线程的线程池 。
    每个线程池中的线程都可以执行MyTask类的实例,MyTask类实现了Runnable接口,并重写了run()方法,在方法中模拟了一个需要执行1秒钟的任务 。
    在main函数中,创建MyTask类的实例,并调用ExecutorService的execute()方法提交给线程池执行 。
    execute()方法会将任务提交给线程池中的一个空闲线程执行 。
    最后调用ExecutorService的shutdown()方法关闭线程池 。
    需要注意的是,shutdown()方法会等待所有线程执行完毕后才会关闭线程池,如果需要立即关闭线程池,可以使用shutdownNow()方法 。
    Callable实现多线程Callable是Java中的一个接口,与Runnable接口类似,都用于封装一个线程执行的任务 。
    不同的是,Callable接口的call()方法可以返回一个结果,而Runnable接口的run()方法没有返回值 。
    使用Callable实现多线程,通常需要以下步骤:
    1. 创建一个实现了Callable接口的类,实现call()方法,并在方法中编写线程执行的代码 。
    2. 创建一个ExecutorService对象,可以使用Executors类提供的静态方法创建线程池,如newFixedThreadPool()、newCachedThreadPool()、newSingleThreadExecutor()等 。
    3. 将Callable对象提交给ExecutorService对象执行,可以使用submit()方法提交 。
    4. 调用Future对象的get()方法获取Callable线程执行的结果 。
    5. 在程序完成时,调用shutdown()方法关闭线程池,或使用awaitTermination()方法等待所有线程执行完毕 。
    import java.util.concurrent.*; public class CallableDemo {public static void main(String[] args) throws Exception {// 创建一个线程池ExecutorService executor = Executors.newFixedThreadPool(10);// 提交10个Callable任务给线程池执行Future<Integer>[] results = new Future[10];for (int i = 0; i < 10; i++) {Callable<Integer> task = new MyTask(i);results[i] = executor.submit(task);}// 输出Callable任务的执行结果for (int i = 0; i < 10; i++) {Integer result = results[i].get();System.out.println("Task " + i + " result is " + result);}// 关闭线程池executor.shutdown();}} class MyTask implements Callable<Integer> {private int id;public MyTask(int id) {this.id = id;}public Integer call() throws Exception {System.out.println("Task " + id + " is running");Thread.sleep(1000);// 模拟任务执行时间return id * 10;}}首先创建一个线程池,然后提交10个Callable任务给线程池执行 。每个Callable任务都是MyTask类的实例,MyTask类实现了Callable接口,并重写了call()方法,在方法中模拟了一个需要执行1秒钟的任务,并返回一个结果 。
    详细解释如下:
    1. 创建一个线程池,通过调用Executors的静态方法newFixedThreadPool(10),创建了一个固定大小为10的线程池 。
    2. 在for循环中,通过创建MyTask类的实例,将其封装为Callable对象,并通过ExecutorService的submit()方法提交给线程池执行 。submit()方法会返回一个Future对象,代表了Callable任务的执行结果 。
    3. 在for循环中,通过Future数组记录每个Callable任务的执行结果,可以通过调用get()方法获取Callable任务的执行结果 。如果Callable任务还没有执行完成,get()方法会阻塞当前线程,直到任务执行完成并返回结果 。如果任务执行过程中发生异常,get()方法会抛出ExecutionException异常 。


      推荐阅读