Java:线程池、Lambda表达式

1、线程-等待唤醒机制-线程间通信

1)、当一个工作需要多个线程同时配合完成,这就需要多个线程间进行通信,以保证这个工作能够完整的完成,这种互相配合的方式就叫做线程间通信

2、线程-等待唤醒机制-等待与唤醒机制

1)、等待唤醒机制就是线程间通信的一种体现

2)、工作形式:

一个线程做一些准备工作

另一个线程做正常的工作

由于线程在运行时是无序的,第二个线程工作时,有可能第一个线程的准备工作还没有做好。这时就需要第二个线程主动的进入等待,然后第一个线程进入开始准备工作,准备工作完成后,唤醒第二个线程开始正常工作

3、线程-等待唤醒机制-生产者与消费者的问题

1)、没有线程间通信的实现:

Java:线程池、Lambda表达式_第1张图片

包子生产者可能没有生产好包子,消费者就会来“拿“包子,这时消费者可能会拿到空值,所以就需要线程间通信

2)、加入线程间通信的实现:

Java:线程池、Lambda表达式_第2张图片

加入线程间通信后就实现了生产者生产出包子,才唤醒消费者来“拿”包子,这样消费者就不会拿到空值

4、线程池-线程池思想概述

1)、线程池:存储了若干多个线程对象的一个容器

2)、对于一个线程对象只能启动一次,再次使用就要再次创建一个线程对象,创建线程对象是耗时操作,程序中要反复使用同一个线程,就要反复创建线程,效率低

3)、线程池思想:在程序启动时,会先创建若干多的线程对象。并存储在一个“线程池”。如果有需要时,取出一个线程对象,并执行它。执行完毕,线程池会回收这个线程对象,如果再次需要时,可以再次取出,并执行,所以,线程池中的线程对象是可以反复使用的。这样就避免 了反复创建线程对象,从而提高了程序的执行效率

5、线程池-线程池概念

线程池类:ExecutorService:缓存大量的线程对象,并可以反复重用他们

6、线程池-线程池的使用

有重用价值的线程对象才值得放在线程池中

public static void main(String[] args) {
    //不使用线程池--两次使用一个线程,供需要10秒
    /*MyThread t = new MyThread();//5秒

    t.start();

    //第二次再次想使用这个线程
    t = new MyThread();//5秒
    t.start();*/

    //使用线程池
    //创建线程池对象
    ExecutorService service = Executors.newFixedThreadPool(2);
    //创建线程对象
    MyThread t = new MyThread();//5秒

    //第一次执行此线程--交给"线程池”去执行,线程池执行后,会将此线程对象"缓存",可以重用
    service.submit(t);

    //第二次执行此线程
    service.submit(t);

    //第三次执行此线程
    service.submit(t);

    //.....

    //关闭线程池
    service.shutdown();

}

7、Lambda表达式-回顾冗余的Runnable代码

对线程的匿名内部类的简写形式

public class Demo {
    public static void main(String[] args) {
        //1.方式一:制作Runnable子类的方式
         MyRunnable myRunnable = new MyRunnable();

        Thread t = new Thread(myRunnable);
        t.start();

        //2.方式二:匿名内部类的方式
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    System.out.println("i = " + i);
                }
            }
        });
        t2.start();

        //3.方式三:使用Lambda的方式
        Thread t3 = new Thread(()->{
            for (int i = 0; i < 100; i++) {
                System.out.println("i = " + i);
            }
        });
        t3.start();
    }
}

8、Lambda表达式-体验Lambda的更优写法-示意图

Java:线程池、Lambda表达式_第3张图片

9、Lambda表达式-编程思想转换及函数式编程思想概述

1)、编程思想转换:将“以什么形式做”转换为“怎么做”

2)、“函数式编程”思想:当调用的方法需要一个接口类型时,就可以考虑直接传入一个代替的函数(方法),无用的语句直接省略

10、Lambda表达式-Lambda的使用前提-标准格式

使用前提:(具备以下条件,才可以使用Lambda表达式)

1)、必须要是一个接口类型;

2)、且接口中有且只有一个抽象方法–函数式接口

标准格式;

1)、一对小括号,内容是形参

2)、一个右箭头:->

3)、一对大括号–方法体

举例:

1.new Thread(()->{System.out.println("线程开始运行...");}).start();
//2.使用匿名内部类:
Runnable r = new Runnable(){
    public void run(){
        System.out.println("线程开始运行");
    }
};
Thread t = new Thread(r);
t.start();
//使用Lambda:
Runnable r = ()->{System.out.println("线程开始运行...");};
Thread t = new Thread(r);
t.start();

11、Lambda表达式-练习-Lambda的标准格式(无参无返回值)

//函数式接口--有,且只有一个抽象方法
interface IA{
    public void show();

}
class SubClass implements IA{
    @Override
    public void show() {
        System.out.println("子类是show()....");
    }
}
public class Demo {
    public static void main(String[] args) {
        //1.传递子类对象
        fun(new SubClass());
        //2.使用匿名内部类
        fun(new IA(){
            @Override
            public void show() {
                System.out.println("匿名内部子类的show()....");
            }
        });
        //3.Lambda表达式
        fun(()->{
            System.out.println("Lambda的show()....");
        });
    }

    public static void fun(IA ia) {
        ia.show();
    }
}

12、Lambda表达式-练习-Lambda的标准格式(有参有返回值)

1)、自定义接口

interface IA{
    public int calc(int a, int b);
}

public class Demo {
    public static void main(String[] args) {
        //2.匿名子类对象
        fun(new IA(){
            @Override
            public int calc(int a, int b) {
                return a + b;
            }
        },10,20);
        //3.使用Lambda
        fun((int x,int y)->{return x * y;},10,20);
    }

    public static void fun(IA ia, int m, int n) {
        int result = ia.calc(m, n);
        System.out.println("结果是:" + result);
    }
}

2)、类库中接口的例子

public class Demo {
    public static void main(String[] args) {
        List stuList = new ArrayList<>();

        stuList.add(new Student("张三1", 17));
        stuList.add(new Student("张三2", 16));
        stuList.add(new Student("张三3", 19));
        stuList.add(new Student("张三4", 15));

        //1.使用匿名内部类的方式
        Collections.sort(stuList, new Comparator() {
            @Override
            public int compare(Student o1, Student o2) {
                return o1.getAge() - o2.getAge();
            }
        });
        //2.使用Lambda
        Collections.sort(stuList,(Student o1, Student o2)->{
            return o1.getAge() - o2.getAge(); 
        });

        System.out.println(stuList);
    }
}

13、Lambda表达式-练习-Lambda的标准格式(有参无返回值)

interface IA{
    public void show(int a,int b);
}
public class Demo {
    public static void main(String[] args) {
        //1.匿名子类
        fun(new IA() {
            @Override
            public void show(int a, int b) {
                System.out.println(a + b);
            }
        }, 10, 20);
        //2.使用Lambda
        fun((int a, int b) -> {System.out.println(a * b); }, 10, 20);

    }

    public static void fun(IA a, int m, int n) {
        a.show(m, n);
    }
}

14、Lambda表达式-Lambda的省略格式及省略原则

例子:

//2.Lambda表达式--完整格式
fun((int x, int y) -> {return x + y;}, 10, 20);

//3.简写的Lambda
fun((x, y) -> x + y, 10, 20);

省略规则:

1)、形参:Lambda中的形参类型都可以省略

2)、形参:如果只有一个参数,形参类型和小括号都可以省略

​ (要省略小括号,必须省略形参类型)

3)、方法体:如果方法体中只有一条语句,可以应用省略规则:

有返回值:可以省略大括号、return关键、分号(要省全省)

无返回值:可以省略大括号、分号(要省全省)

复习

  • [ ] 能够理解线程通信概念

    多个线程共同协作完成同一个任务,就需要线程间进行通信

  • [ ] 能够理解等待唤醒机制

    等待唤醒机制是线程间通信的一种体现

    一个线程在执行时发现准备工作不满足,就会进入等待状态,另一个线程开始做准备工作,准备工作完成后,就会唤醒等待中的线程

  • [ ] 能够描述Java中线程池运行原理

    将多个复用的线程对象放在一个容器中,这个容器就是线程池

  • [ ] 能够理解函数式编程相对于面向对象的优点

    函数式编程思想更在意与怎么做,而不是以什么形式去做

  • [ ] 能够掌握Lambda表达式的标准格式

    new Thread(()->{方法体;}).start();
  • [ ] 能够使用Lambda标准格式使用Runnable与Comparator接口

  • [ ] 能够掌握Lambda表达式的省略格式与规则

  • [ ] 能够使用Lambda省略格式使用Runnable与Comparator接口

  • [ ] 能够通过Lambda的标准格式使用自定义的接口(有且仅有一个抽象方法)

  • [ ] 能够通过Lambda的省略格式使用自定义的接口(有且仅有一个抽象方法)

  • [ ] 能够明确Lambda的两项使用前提

你可能感兴趣的:(Java)