学习记录——进阶版07
程序员文章站
2022-03-26 18:47:34
@学习记录开始学习Java遵从同学的指导,从Java se开始学习黑马的JavaSE零基础入门【】教学目标: 能够描述Java中多线程运行原理 能够使用继承类的方式创建多线程 能够使用实现接口的方式创建多线程 能够说出实现接口方式的好处 能够解释安全问题出现的原因 能够使用同步代码块解决线程安全问题 能够使用同步方法解决线程安全问题 能够说出线程6个状态的名称第一章 线程1.1 多线程原理18-02 多线程原理-随机性打印结果......
@学习记录
开始学习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
下一篇: Mysql引起索引失效的条件
推荐阅读
-
36篇博文带你学完opencv :python+opencv进阶版学习笔记目录
-
07.Django学习之model进阶
-
学习记录——进阶版07
-
荐 数据结构の学习记录(进阶篇3):探密红黑树
-
SQL入门经典(第四版)学习记录——SQL语法(二)
-
SQL入门经典(第四版)学习记录——欢迎来到SQL世界(一)
-
UE4 C++学习记录-代码更换材质(4.22.3版本)
-
PTA浙大版《数据结构学习与实验指导(第2版)》题目集----进阶实验1-3.1 两个有序序列的中位数
-
web进阶之jQuery操作DOM元素&&MySQL记录操作&&PHP面向对象学习笔记,web进阶jquerydom
-
SpringBootSecurity学习(07)网页版登录整合JDBC