Java学习记录day21-线程池,Stream流

本文介绍了Java中的线程池概念,强调了线程池的三大优势:资源节省、响应速度提升和线程管理。详细讲解了如何创建线程池,包括`newFixedThreadPool`方法,并展示了提交任务到线程池的API。同时,文章还探讨了Java 8引入的Stream流,阐述了Stream流解决的问题,如集合操作简化,以及流的核心思想。并列举了一些常用的Stream流方法,如forEach、filter和map等。最后,提到了Stream流的终结与非终结方法,并简要讨论了收集Stream流的过程。

什么是线程池。

线程池:其实就是一个容纳多个线程的容器,其中的线程可以反复使用,
省去了频繁创建和销毁线程对象的操作,无需反复创建线程而消耗过多资源。

为什么要用线程池:
合理利用线程池能够带来三个好处
1.降低资源消耗。减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。
2.提高响应速度
3.提高线程的可管理性
线程池的核心思想:线程复用。同一个线程可以被重复使用。

线程池的创建方式一

线程池在Java中的代表: ExecutorService

创建线程池的API:
java.util.concurrent.Executors类下:
– public static ExecutorService newFixedThreadPool(int nThreads)`:
返回线程池对象。(创建的是有界线程池,也就是池中的线程个数可以指定最大数量)

往线程池ExecutorService中创建线程的API:
1.public Future<?> submit(Runnable task)
2. Future submit(Callable task);
线程池启动后是不会死亡的,因为后续还要重复使用的。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Demo1 {
    public static void main(String[] args) {
        //创建一个线程池
        ExecutorService pools = Executors.newFixedThreadPool(3);
        Runnable target = new MyRunnable();
  //加线程执行就好
        pools.submit(target);
        pools.submit(target);
        pools.submit(target);
  //重复调用上面一个线程
        pools.submit(target);
//等线程执行完后关闭线程
        pools.shutdown();
//  立即关闭线程,不管是不是执行完了
// pools.shutdown();

    }
}
class MyRunnable implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName()+"=>"+i);
        }
    }
}

线程池的创建方式二

线程池在Java中的代表: ExecutorService

创建线程池的API:
java.util.concurrent.Executors类下:
public static ExecutorService newFixedThreadPool(int nThreads)`:返回线程池对象。(创建的是有界线程池,也就是池中的线程个数可以指定最大数量)
往线程池中创建线程的API:
1.public Future<?> submit(Runnable task)
2. Future submit(Callable task);

public class ThreadPools {
    public static void main(String[] args) throws Exception {
        // 1.新建一个只能存储3个线程的线程池。
        ExecutorService pools = Executors.newFixedThreadPool(3);
        Future<Integer> task1 = pools.submit(new MyCallable(5));
        Future<Integer> task2 = pools.submit(new MyCallable(10));

        Future<Integer> task3 = pools.submit(new MyCallable(15));
        Future<Integer> task4 = pools.submit(new MyCallable(20));

        System.out.println(task1.get());
        System.out.println(task2.get());
        int rs = task3.get();
        System.out.println(rs);
        System.out.println(task4.get());
    }
}

class MyCallable implements Callable<Integer>{
    private int n ;
    public MyCallable(int n){
        this.n  = n;
    }
    @Override
    public Integer call() throws Exception {
        int count = 0 ;
        for(int i = 1; i <= n ; i++ ){
            count+=i;
            System.out.println(Thread.currentThread().getName() + ":开始累加"+i);
        }
        return count;
    }

    public int getN() {
        return n;
    }

    public void setN(int n) {
        this.n = n;
    }
}

Stream流

什么是Stream流?
在Java 8中,得益于Lambda所带来的函数式编程,
引入了一个全新的Stream流概念,用于解决已有集合/数组类库既有的弊端。
Stream流能解决什么问题?
可以解决已有集合类库或者数组API的弊端。
Stream流可以简化集合的操作,Stream流提供了强大的元素筛选机制。
代码可读性更好,更加优雅!

##Stream流的获取

 流式思想的核心:是先得到集合或者数组的Stream流(就是一根传送带)
             然后就在这个Stream流操作集合或者数组的元素。
             Stream流简化替代集合操作的API.
 集合获取流的API:
     (1) default Stream<E> stream();

 */
public class StreamDemo01 {
    public static void main(String[] args) {
        /** --------------------Collection集合获取流-------------------------------   */
        // Collection集合如何获取Stream流。
        Collection<String> lists = new ArrayList<>();
        Stream<String> ss = lists.stream();

        /** --------------------Map集合获取流-------------------------------   */
        Map<String, Integer> map = new HashMap<>();
        // 先获取键的Stream流。
        Stream<String> keyss = map.keySet().stream();
        // 在获取值的Stream流
        Stream<Integer> valuess = map.values().stream();
        // 获取键值对的Stream流(key=value: Map.Entry<String,Integer>)
         // key=value  , key = value
        Stream<Map.Entry<String,Integer>> keyAndValues = map.entrySet().stream();

        /** ---------------------数组获取流------------------------------   */
        // 数组也有Stream流。
        String[] arrs = new String[]{"Java", "JavaEE" ,"Spring Boot"};
        Stream<String> arrsSS1 = Arrays.stream(arrs);
        Stream<String> arrsSS2 = Stream.of(arrs);

    }
}

Stream流的常用方法。

流式编程的核心思想:是把集合或者数组转成Stream流,然后
通过调用流的方法,完成各种功能操作。
Stream流的方法:
forEach , count, filter , limit , skip , map 把传送带上的每个元素进行加工再放上去 concat:连接流。
终结与非终结方法
终结方法一旦调用就没有Stream流返回了,操作就结束了。(传送带的使命就结束了!)
非终结方法是每次调用都会返回一个新的Stream流,程序员就可以继续操作。
常见终结方法:foreach count

public class StreamDemo01 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("张无忌");
        list.add("周芷若");
        list.add("周伯通");
        list.add("赵敏");
        list.add("张强");
        list.add("张三丰");

        // forEach 遍历
        list.stream().filter(s-> s.startsWith("周")).forEach(System.out::println);

        // count统计个数
        long count = list.stream().filter(s-> s.startsWith("周")).count();
        System.out.println(count);

        // limit 只要前2个元素
        list.stream().filter(s -> s.length() == 3).limit(2).forEach(System.out::println);

        // skip 跳过前2个
        list.stream().filter(s -> s.length() == 3).skip(2).forEach(System.out::println);
    }
}

收集Stream流。

      Stream流的作用是为了帮助操作集合,操作完的数据依然是在Stream流上。
      但是实际开发的时候,数据最终的形式还应该是集合或者数组。
 开发中:集合 -> 通过Stream流辅助操作它 -> 转回成集合(收集Stream流)。
 小结:
        流像水一样,只能用一次,
        一个Stream流只能用一次!!!
public class StreamDemo01 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("张无忌");
        list.add("周芷若");
        list.add("周伯通");
        list.add("赵敏");
        list.add("张强");
        list.add("张三丰");
        list.add("张三丰");

        //  forEach 遍历
        Stream<String> ss = list.stream().filter(s -> s.startsWith("张") && s.length()==3);
        // 收集Stream流成为一个集合: 面向对象的思想设计的。
        List<String> names1 = ss.collect(Collectors.toList());
        System.out.println(names1);

        Stream<String> ss1 = list.stream().filter(s -> s.startsWith("张") && s.length()==3);
        Set<String> names2 = ss1.collect(Collectors.toSet());
        System.out.println(names2);

        // 把流收集成数组
        Stream<String> ss2 = list.stream().filter(s -> s.startsWith("张") && s.length()==3);
        Object[] objs = ss2.toArray();
        System.out.println(Arrays.toString(objs));

        // 收集成特定类型的数组!!
        Stream<String> ss3 = list.stream().filter(s -> s.startsWith("张") && s.length()==3);
        String[] objs1 =  ss3.toArray(String[]::new);
        System.out.println(Arrays.toString(objs1));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值