@学习记录

开始学习Java

遵从同学的指导,从Java se开始学习

黑马的JavaSE零基础入门【线程池、Lambda表达式】

第一章 等待唤醒机制

1.1 线程间通信

1.2 等待唤醒机制

18-03 等待唤醒机制概述

18-04 等待唤醒机制需求分析

1.3 生产者与消费者问题

18-05 等待唤醒机制代码实现——包子类和包子铺类
package day_07ThreadAndLambda.demo01WaitAndNotify;

/* 资源类:包子 设置包子的属性 皮 馅 包子的状态:有 ture; 没有 false */
public class BaoZi { 
    String pi;
    String xian;
    // 设置包子的初始值为false
    boolean state = false;

}

package day_07ThreadAndLambda.demo01WaitAndNotify;

/* 生产者(包子铺)类:是一个线程类,可以继承Thread 设置线程任务:生产包子 对包子的状态进行判断 true:有包子 包子铺调用wait方法进入等待状态 false:没有包子 包子铺生产包子 包子铺生产好了包子 修改包子的状态为true 唤醒吃货线程,让他吃包子 注意: 包子铺线程和包子线程的关系 --> 通信(互斥),必须使用同步技术保证量的线程只有一个在执行 锁对象必须保证唯一,可以使用包子对象作为锁对象 包子铺类和吃货的类需要把包子对象作为参数传递进来: 1.需要在成员变量位置创建一个包子类 2.使用带参数构造方法,为这个包子变量赋值 */
public class BaoZiPu extends Thread{ 
    // 1.需要在成员变量位置创建一个包子类
    private BaoZi baoZi;
    // 2.使用带参数构造方法,为这个包子变量赋值
    public BaoZiPu(BaoZi baoZi) { 
        this.baoZi = baoZi;
    }
    // 重写线程任务,生产包子
    @Override
    public void run() { 
        int count = 0;
        // 使用同步技术保证量的线程只有一个在执行
        synchronized (baoZi) { 
            // 对包子的状态进行判断
            if (baoZi.state == true) { 
                // 包子铺调用wait方法进入等待状态
                try { 
                    baoZi.wait(); // 必须使用锁对象调用wait方法
                } catch (InterruptedException e) { 
                    e.printStackTrace();
                }
            }

            System.out.println("包子铺正在生产");
            // 生产两种包子
            if (count % 2 == 0) { 
                baoZi.pi = "老窖";
                baoZi.xian = "三鲜";
            } else { 
                baoZi.pi = "发面";
                baoZi.xian = "荠菜";
            }

            // 包子铺生产包子
            try { 
                Thread.sleep(1000);
                System.out.println("包子铺生产好包子");
            } catch (InterruptedException e) { 
                e.printStackTrace();
            }
            // 修改包子的状态为true
            baoZi.state = true;
            // 唤醒吃货线程,让他吃包子
            baoZi.notify();
            System.out.println("包子已经生产好,吃货可以开吃了");


        }
    }
}

18-06 等待唤醒机制代码实现——吃货类和测试类
package day_07ThreadAndLambda.demo01WaitAndNotify;

/* 消费者(吃货)类是一个线程类,可以继承Thread 设置线程任务:吃包子 对包子的状态进行判断 false:没有包子 吃货调用wait方法进入等待状态 true:有包子 吃货吃包子 吃货吃完包子 修改包子的状态为false 吃货唤醒包子铺线程,生产包子 */
public class ChiHuo extends Thread{ 
    // 1.需要在成员变量位置创建一个包子类
    private BaoZi baoZi;

    // 2.使用带参数构造方法,为这个包子变量赋值
    public ChiHuo(BaoZi baoZi) { 
        this.baoZi = baoZi;
    }

    // 设置线程任务:吃包子
    @Override
    public void run() { 
        // 使用同步技术保证量的线程只有一个在执行
        synchronized (baoZi) { 
            if (baoZi.state == false) { 
                // 吃货调用wait方法进入等待状态
                try { 
                    baoZi.wait();
                } catch (InterruptedException e) { 
                    e.printStackTrace();
                }
            }

            // 线程被唤醒之后执行的代码:吃包子
            System.out.println("吃货吃包子:" + baoZi.pi + baoZi.xian);
            try { 
                Thread.sleep(100);
            } catch (InterruptedException e) { 
                e.printStackTrace();
            }
            System.out.println("吃货吃完包子");
            // 修改包子的状态为false
            baoZi.state = false;
            // 吃货唤醒包子铺线程,生产包子
            baoZi.notify();
            System.out.println("包子铺需要开始生产包子");
            System.out.println("======================");
        }
    }
}

package day_07ThreadAndLambda.demo01WaitAndNotify;

/* 测试类: 包含main方法,程序执行的入口,启动程序 创建包子类对象 创建包子铺线程,开启,生产包子 创建吃货线程,开启,吃包子 */
public class Demo { 
    public static void main(String[] args) { 
        // 创建包子类对象
        BaoZi baoZi = new BaoZi();
        // 创建包子铺线程,开启,生产包子
        new BaoZiPu(baoZi).start();
        // 创建吃货线程,开启,吃包子
        new ChiHuo(baoZi).start();
    }
}

第二章 线程池

2.1 线程池思想概述

2.2 线程池概念

18-07 线程池的概念和原理

2.3 线程池的使用

18-08 线程池的代码实现
package day_07ThreadAndLambda.demo02ThreadPool;

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

/* 线程池:JDK1.5之后提供的 java.util.concurrent.Executors:线程池的工厂类,用来生成线程池 Executors类中的静态方法: static ExecutorService newFixedThreadPool(int nThreads) 创建一个可重复利用固定线程数的线程池 参数:nThreads 创建线程池中包含的线程数量 返回值:ExecutorService接口,返回的式ExecutorService接口的实现类对象,可以使用ExecutorService接口接收(面向接口编程) java.util.concurrent.ExecutorService线程池接口 用来从线程池中获取线程,调用start方法,执行线程任务 submit(Runnable task) 提交一个Runnable任务用于执行 关闭/销毁线程池的方法 void shutdown() 线程池的使用步骤: 1.使用线程池的工厂类Executors里面提供的静态方法newFixedThreadPool创建一个指定线程数量的线程池 2.创建一个类,实现Runnable接口,重写run方法,设置线程任务 3.调用ExecutorService中的方法submit,传递线程任务(实现类),开启线程,执行run方法 4.调用ExecutorService中的方法shutdown销毁线程池(不建议执行) */
public class Demo01ThreadPool { 
    public static void main(String[] args) { 
        // 1.使用线程池的工厂类Executors里面提供的静态方法newFixedThreadPool创建一个指定线程数量的线程池
        ExecutorService executorService = Executors.newFixedThreadPool(2);

        // 3.调用ExecutorService中的方法submit,传递线程任务(实现类),开启线程,执行run方法
        executorService.submit(new RunnableImpl());
        executorService.submit(new RunnableImpl());
        executorService.submit(new RunnableImpl());

        // 4.调用ExecutorService中的方法shutdown销毁线程池(不建议执行)
        executorService.shutdown();
    }
}

package day_07ThreadAndLambda.demo02ThreadPool;

// 2.创建一个类,实现Runnable接口,重写run方法,设置线程任务
public class RunnableImpl implements Runnable{ 

    @Override
    public void run() { 
        System.out.println(Thread.currentThread().getName());
    }
}

第三章 Lambda表达式

3.1 函数式编程思想概述

18-09 函数式编程思想概述

3.2 冗余的Runnable代码

传统写法
代码分析

18-10 冗余的Runnable代码
package day_07ThreadAndLambda.demo03Lambda;

/* 创建Runnable接口的实现类,重写run方法,设置线程任务 */
public class RunnableImpl implements Runnable{ 
    @Override
    public void run() { 
        System.out.println(Thread.currentThread().getName());
    }
}

package day_07ThreadAndLambda.demo03Lambda;

/* 使用实现Runnable接口的方式实现多线程程序 */
public class Demo01Runnable { 
    public static void main(String[] args) { 
        // 创建Runnable接口的实现类对象
        RunnableImpl runnable = new RunnableImpl();
        // 创建Thread类对象,构造方法中传递Runnable接口的实现类
        Thread thread = new Thread(runnable);
        // 调用start方法开启新线程,执行run方法
        thread.start();

        // 简化代码,使用匿名内部类实现多线程程序
        new Thread(new Runnable() { 
            @Override
            public void run() { 
                System.out.println(Thread.currentThread().getName());
            }
        }).start();
    }
}

3.3 编程思想转换

做什么,而不是怎么做
生活举例

3.4 体验Lambda的更优写法

18-11 编程思想转换以及体验Lambda的更优写法
package day_07ThreadAndLambda.demo03Lambda;

public class Demo02Lambda { 
    public static void main(String[] args) { 
        // 使用匿名内部类的方式实现多线程
        new Thread(new Runnable() { 
            @Override
            public void run() { 
                System.out.println(Thread.currentThread().getName());
            }
        }).start();

        // 使用Lambda表达式实现多线程
        new Thread(()->{ 
            System.out.println(Thread.currentThread().getName());
        }
        ).start();
    }
}

3.5 回顾匿名内部类

使用实现类
使用匿名内部类
匿名内部类的好处与弊端
语义分析

3.6 Lambda标准格式

18-12 Lambda标准格式
/* Lambda表达式的标准格式: 由三部分组成:一些参数,一个箭头,一段代码 格式:(参数列表)-> {一些重写方法的代码} */

3.7 练习:使用Lambda标准格式(无参无返回)

题目
解答

18-13 Lambda标准格式(无参无返回)练习
package day_07ThreadAndLambda.demo04Lambda;

/* 需求: 给定一个厨子Cook接口,内含唯一的抽象方法makeFood,且无参无返回 使用Lambda的标准格式调用invokeCook方法,打印输出”吃饭啦“字样 */
public class Demo01Cook { 
    public static void main(String[] args) { 
        // 调用invokeCook方法,参数是Cook接口,传递Cook接口的匿名内部类对象
        invokeCook(new Cook() { 
            @Override
            public void makeFood() { 
                System.out.println("吃饭啦");
            }
        });

        // 使用Lambda标准格式,简化程序
        invokeCook(() -> { 
            System.out.println("吃饭啦!");
        });
    }

    // 调用一个方法,参数传递Cook接口,方法内部调用Cook接口中的方法makeFood
    public static void invokeCook(Cook cook) { 
        cook.makeFood();
    }
}

package day_07ThreadAndLambda.demo04Lambda;

/* 给定一个厨子Cook接口,内含唯一的抽象方法makeFood,且无参无返回 */
public interface Cook { 
    public abstract void makeFood();
}

3.8 Lambda的参数和返回值

传统写法
代码分析
Lambda写法

18-14 Lambda标准格式(有参有返回)练习
package day_07ThreadAndLambda.demo05Lambda;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;

/* 需求: 使用数组存储多个Person对象 对数组中的Person对象使用Arrays的sort方法通过年龄进行升序排序 */
public class Demo01Arrays { 
    public static void main(String[] args) { 
        // 创建数组存储多个Person对象
        Person[] list = { 
                new Person("法外",20),
                new Person("狂徒",18),
                new Person("张三",22)
        };


        // 对数组中的Person对象使用Arrays的sort方法通过年龄进行升序(前边-后边)排序
       /* Arrays.sort(list, new Comparator<Person>() { @Override public int compare(Person o1, Person o2) { return o1.getAge() - o2.getAge(); } });*/

        // 使用Lambda表达式简化匿名内部类
        Arrays.sort(list, (Person o1, Person o2) ->{ 
            return o1.getAge() - o2.getAge();

        });

        // 遍历数组
        for (Person person : list) { 
            System.out.println(person);
        }
    }
}

package day_07ThreadAndLambda.demo05Lambda;

public class Person { 
    private String name;
    private int age;

    public Person(String name, int age) { 
        this.name = name;
        this.age = age;
    }

    public Person() { 
    }

    @Override
    public String toString() { 
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public String getName() { 
        return name;
    }

    public void setName(String name) { 
        this.name = name;
    }

    public int getAge() { 
        return age;
    }

    public void setAge(int age) { 
        this.age = age;
    }
}

3.9 练习:使用Lambda标准格式(有参有返回)

题目
解答

18-15 Lambda标准格式(有参有返回)练习(自定义接口)
package day_07ThreadAndLambda.demo06Lambda;

/* 需求: 给定一个计算器Calculator接口,内涵抽象方法calc可以将两个int数字相加得到和 使用Lambda的标准格式调用invokeCalc方法,完成120和130的相加计算 */
public class Demo01Calculator { 
    public static void main(String[] args) { 
        invokeCalc((int a, int b) -> { 
            return a + b;
        }, 120, 130);

    }

    public static void invokeCalc(Calculator calculator,int a, int b) { 
        int result = calculator.calc(a, b);
        System.out.println(result);
    }
}

package day_07ThreadAndLambda.demo06Lambda;

/* 给定一个计算器Calculator接口,内涵抽象方法calc可以将两个int数字相加得到和 */
public interface Calculator { 
    public abstract int calc(int a, int b);

}

3.10 Lambda省略格式

可推导即可省略
胜率规则

3.11 练习:使用Lambda省略格式

题目
解答

3.12 Lambda的使用前提

18-15 Lambda省略格式和Lambda的使用前提
package day_07ThreadAndLambda.demo03Lambda;

/* Lambda表达式的标准格式: 由三部分组成:一些参数,一个箭头,一段代码 格式:(参数列表)-> {一些重写方法的代码} */
public class Demo02Lambda { 
    public static void main(String[] args) { 
        // 使用匿名内部类的方式实现多线程
        new Thread(new Runnable() { 
            @Override
            public void run() { 
                System.out.println(Thread.currentThread().getName());
            }
        }).start();

        // 使用Lambda表达式实现多线程
        new Thread(()->{ 
            System.out.println(Thread.currentThread().getName());
        }
        ).start();

        // 优化省略Lambda
        new Thread(()->System.out.println(Thread.currentThread().getName())).start();
    }
}

package day_07ThreadAndLambda.demo04Lambda;

/* 需求: 给定一个厨子Cook接口,内含唯一的抽象方法makeFood,且无参无返回 使用Lambda的标准格式调用invokeCook方法,打印输出”吃饭啦“字样 */
public class Demo01Cook { 
    public static void main(String[] args) { 
        // 调用invokeCook方法,参数是Cook接口,传递Cook接口的匿名内部类对象
        invokeCook(new Cook() { 
            @Override
            public void makeFood() { 
                System.out.println("吃饭啦");
            }
        });

        // 使用Lambda标准格式,简化程序
        invokeCook(() -> { 
            System.out.println("吃饭啦!");
        });

        // 优化省略Lambda
        invokeCook(() -> System.out.println("吃饭啦!"));
    }

    // 调用一个方法,参数传递Cook接口,方法内部调用Cook接口中的方法makeFood
    public static void invokeCook(Cook cook) { 
        cook.makeFood();
    }
}

package day_07ThreadAndLambda.demo05Lambda;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;

/* 需求: 使用数组存储多个Person对象 对数组中的Person对象使用Arrays的sort方法通过年龄进行升序排序 */
public class Demo01Arrays { 
    public static void main(String[] args) { 
        // 创建数组存储多个Person对象
        Person[] list = { 
                new Person("法外",20),
                new Person("狂徒",18),
                new Person("张三",22)
        };


        // 对数组中的Person对象使用Arrays的sort方法通过年龄进行升序(前边-后边)排序
       /* Arrays.sort(list, new Comparator<Person>() { @Override public int compare(Person o1, Person o2) { return o1.getAge() - o2.getAge(); } });*/

        /*// 使用Lambda表达式简化匿名内部类 Arrays.sort(list, (Person o1, Person o2) ->{ return o1.getAge() - o2.getAge(); });*/

        // 优化省略Lambda
        Arrays.sort(list, (o1, o2) ->o1.getAge() - o2.getAge());

        // 遍历数组
        for (Person person : list) { 
            System.out.println(person);
        }
    }
}

package day_07ThreadAndLambda.demo06Lambda;

/* 需求: 给定一个计算器Calculator接口,内涵抽象方法calc可以将两个int数字相加得到和 使用Lambda的标准格式调用invokeCalc方法,完成120和130的相加计算 */
public class Demo01Calculator { 
    public static void main(String[] args) { 
        invokeCalc((int a, int b) -> { 
            return a + b;
        }, 120, 130);

        // 优化省略Lambda
        invokeCalc((a, b) -> a + b, 120, 130);

    }

    public static void invokeCalc(Calculator calculator,int a, int b) { 
        int result = calculator.calc(a, b);
        System.out.println(result);
    }
}

本文地址:https://blog.csdn.net/weixin_42690266/article/details/113945128