目录

  • 线程的两种执行方式:
  • 1.execute()执行:
  • 2.submit()执行:
  • 两者区别:
  • 线程池的两种关闭方式:
  • 1.shutdown():
  • 1.shutdownNow():
  • 两者区别:
  • 线程池的状态(5种):
  • 线程池的状态转化图:


线程的两种执行方式:

1.execute()执行:

(new Runnable)无返回值的:

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


public class ThreadDemo58 {
    public static void main(String[] args) {

        // 创建线程池
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                5, 5,
                0, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(5));
        for (int i = 0; i < 11; i++) {
            int finalI = i;
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println("任务:" + finalI + ",线程名:" +
                            Thread.currentThread().getName());
                }
            });
        }
    }
}

2.submit()执行:

(new Runnable无返回值/new Callable有返回值的>

import java.util.Random;
import java.util.concurrent.*;

public class ThreadPoolDemo61 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {

        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                5, 5, 0, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(1000)
        );
        // 返回返回值
        Future<Integer> future = executor.submit(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                int num = new Random().nextInt(10);
                System.out.println("线程池生成了随机数:" + num);
                return num;
            }
        });
        System.out.println("main 得到返回值:" + future.get());
    }
}
两者区别:
  1. execute只能执行Runnable 任务,它是无返回值的; submit 它既能执行Runnable无返回值的任务,也能执行Callable有返回值的任务。
  2. execute执行任务如果有OM异常会将异常打印到控制台; 而submit执行任务出现了OM异常时不会打印异常。

线程池的两种关闭方式:

线程池的特征:线程池相比于线程来说是长生命周期,即使没有任务了,也会运行并等待任务。

1.shutdown():

import java.util.Random;
import java.util.concurrent.*;

public class ThreadDemo62 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {

        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                5, 5, 0, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(1000)
        );
        // 返回返回值
        Future<Integer> future = executor.submit(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                int num = new Random().nextInt(10);
                System.out.println("线程池生成了随机数:" + num);
                return num;
            }
        });
        System.out.println("main 得到返回值:" + future.get());
        // 关闭线程池
        executor.shutdown();
    }
}

1.shutdownNow():

import java.util.Random;
import java.util.concurrent.*;

public class ThreadDemo62 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {

        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                5, 5, 0, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(1000)
        );
        // 返回返回值
        Future<Integer> future = executor.submit(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                int num = new Random().nextInt(10);
                System.out.println("线程池生成了随机数:" + num);
                return num;
            }
        });
        System.out.println("main 得到返回值:" + future.get());
        // 关闭线程池
        executor.shutdownNow();
    }
}
两者区别:

(执行复杂任务时会体现出区别)

  1. shutdown():拒绝新任务加入,等待线程池中的任务队列执行完之后,再停止线程池。最后清空线程池中的线程。
  2. shutdownNow() :拒绝执行新任务,不会等待任务队列中的任务执行完成,就停止线程池。最后清空线程池中的线程。
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadDemo63 {
    public static void main(String[] args) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                10, 10, 0, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(1000)
        );
        for (int i = 0; i < 100; i++) {
            int finalI = i;
            executor.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println(String.format("编号:%d,线程名:%s",
                            finalI, Thread.currentThread().getName()));
                }
            });
        }
        // 正常关闭
        executor.shutdown();
//        executor.shutdownNow();


    }
}

线程池的状态(5种):

注意: 线程池的状态不等于线程的状态(6种))

java线程池 导出线程 java线程池execute方法_java线程池 导出线程

线程池的状态转化图:

java线程池 导出线程 java线程池execute方法_并发编程_02


从上图我们看到线程池总共存在5种状态,分别为:

  • RUNNING:线程池创建之后的初始状态,这种状态下可以执行任务。
  • SHUTDOWN:该状态下线程池不再接受新任务,但是会将工作队列中的任务执行结束。
  • STOP:该状态下线程池不再接受新任务,但是不会处理工作队列中的任务,并且将会中断线程。
  • TIDYING:该状态下所有任务都已终止,将会执行terminated()钩子方法。
  • TERMINATED:执行完terminated()钩子方法之后。

注:线程池的状态只是给开发者使用的,对于客户机是不可见的。