线程的创建

1、继承Thread类
2、实现Runnable接口
3、实现Callable接口
这种方式需要结合FutureTask类使用

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Callable callable = new Callable() {
            @Override
            public Object call() throws Exception {
                return null;
            }
        };
        FutureTask future1 = new FutureTask(() -> {
            int sum = 0;
            for (int i = 0; i < 10; i++) {
                System.out.println(Thread.currentThread().getName()+"---"+i);
                sum += i;
            }
            return sum;
        });
        new Thread(future1).start();

        FutureTask future2 = new FutureTask(() -> {
            int sum = 0;
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName()+"---"+i);
                sum += i;
            }
            return sum;
        });
        new Thread(future2).start();
        System.out.println(future1.get());
        System.out.println(future2.get());

    }

// 运行结果:
Thread-0---0
Thread-0---1
Thread-0---2
Thread-1---0
Thread-0---3
Thread-1---1
Thread-0---4
Thread-1---2
Thread-0---5
Thread-1---3
Thread-1---4
Thread-0---6
Thread-0---7
Thread-0---8
Thread-0---9
45
10

注意:只有线程执行结束后才会执行get(),所以FutureTask也用于闭锁。

闭锁(Latch):一种同步方法,可以延迟线程的进度直到线程到达某个终点状态。通俗的讲就是,一个闭锁相当于一扇大门,在大门打开之前所有线程都被阻断,一旦大门打开所有线程都将通过,但是一旦大门打开,所有线程都通过了,那么这个闭锁的状态就失效了,门的状态也就不能变了,只能是打开状态。也就是说闭锁的状态是一次性的,它确保在闭锁打开之前所有特定的活动都需要在闭锁打开之后才能完成。

Callable 和 Runnable 方式的区别
1> Callable 内部实现call方法,Runnable 内部实现 run方法。
2> Callable 方式有返回值,Runnable没有。
3> Callable 方式可以抛出异常,Runnable只能内部自己处理异常。

4、线程池
提供了一个线程队列,队列中保存着所有等待状态的线程。避免了创建与销毁额外开销,提高了响应的速度

引用:

线程池的体系结构:
java.util.concurrent.Executor : 负责线程的使用与调度的根接口
|--*ExecutorService 子接口: 线程池的主要接口
|--ThreadPoolExecutor 线程池的实现类
|--ScheduledExecutorService 子接口:负责线程的调度
|--ScheduledThreadPoolExecutor :继承 ThreadPoolExecutor, 实现 ScheduledExecutorService
工具类 : Executors
a) ExecutorService newFixedThreadPool() : 创建固定大小的线程池
b) ExecutorService newCachedThreadPool() : 缓存线程池,线程池的数量不固定,可以根据需求自动的更改数量。
c) ExecutorService newSingleThreadExecutor() : 创建单个线程池。线程池中只有一个线程
d) ScheduledExecutorService newScheduledThreadPool() : 创建固定大小的线程,`与ExecutorService 的区别是还可以延迟或定时的执行任务

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        Future submit1 = executorService.submit(() -> {
            int sum = 0;
            for (int i = 0; i < 10; i++) {
                System.out.println(Thread.currentThread().getName() + "---" + i);
                sum += i;
            }
            return sum;
        });
        Future submit2 = executorService.submit(() -> {
            int sum = 0;
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName() + "---" + i);
                sum += i;
            }
            return sum;
        });

        System.out.println(submit1.get());
        System.out.println(submit2.get());

    }

你可能感兴趣的:(线程的创建)