学习目标:
- 熟悉等待唤醒机制;
- 掌握进程池的使用步骤,理解进程池;
- 熟练使用lambda表达式简化代码。
学习内容:
一、等待唤醒机制
1、线程间通信
- 多个线程共同完成一个任务,协调通信,共享数据
2、简介
- 就是多个线程之间的协调(有效利用资源)
3、主要应用方法
- wait
- notify
- notifyAll
4、注意
- wait和notify方法必须使用同一个锁对象才能进行等待唤醒,原因:对应的锁对象可以通过调用notify方法唤醒通过
该对象调用的wait方法的线程; - wait和notify方法属于Object类的方法,原因:锁对象可以是任意对象,而任意对象都是继承了Object类;
- wait和notify方法必须在同步代码块或同步函数中使用,原因:必须通过锁对象调用这两个函数。
二、线程池
1、简介
- 大量的创建线程与销毁线程会极大地降低效率,引入线程池的概念,使得一个线程可以重复利用;
实际上就是一个集合。
2、概念
- 线程池中的线程可以被反复使用
- 在JDK1.5之后引入
3、线程池的使用
- 来源
java.util.concurrent.Executors; 线程池的工厂类,用来生成线程池 - Executors类中的静态方法
- static ExecutorService newFixedThreadPool(int nThreads); 创建一个可重用固定线程数的线程池
- 参数:
int nThreads:创建线程池中包含线程的数量 - 返回值:
ExecutorService接口,返回的是ExecutorService接口的实现类对象,可以使用ExecutorService
接口接收(面向接口编程)
- 线程池接口
- java.util.concurrent.ExecutorService
- 用来从线程池中获取线程,调用start方法,执行线程任务
submit(Runnable task); 提交一个Runnable任务用于执行 - 关闭/销毁线程池方法
void shutdown();
- 使用步骤
- 使用线程池的工厂类中的newFixedThreadPool静态方法生成一个指定线程个数的线程池;
- 创建一个类,实现Runnable接口,重写Run方法,设置线程任务;
- 调用ExecutorService接口中的submit方法,传递线程任务(实现类),开启线程,执行run方法;
- 调用ExecutorService接口中的shutdown方法,销毁线程池(不建议执行)。
三、lambda表达式
1、简介
- 函数式编程思想:强调做什么,而不是以什么形式做;
- JDK1.8之后引入lambda
2、Lambda的更优写法
- “实现Runnable接口,实现线程的创建运行”
- 传统写法
new Thread(new Runnable(){
@override
public void run(){
System.out.println(Thread.currentThread().getName());
}
}).start();
- 优化写法
new Thread(()->{
System.out.println(Thread.currentThread().getName());
}).start();
- 语义分析
- 前面的一对小括号即run方法的参数(无),代表不需要任何条件;
- 中间的一个箭头表示将参数传递给后面的代码;
- 最后的输出语句,即业务逻辑代码。
3、Lambda表达式的标准格式
- 三要素
参数,箭头,代码 - 形式
- (参数列表)->{一些重写方法的代码}
- ()参数列表中的参数之间用逗号分割,没有就空着;
- ->表示将参数传递给后面的代码;
- {}重写接口抽象方法的方法体。
4、省略
- (参数列表):括号中的参数列表的数据类型可以省略,接口中抽象函数的参数列表已经表示;
- (参数列表):括号中参数如果只有一个,括号和类型可以省略;
- (一些代码):如果{}中代码只有一行,那么无论是否又返回值,都可以省略(return、{}、分号),且必须同时省略
5、使用前提
- 必须具有接口,且接口中有唯一的抽象方法;
- 必须具有上下文推断,方法的参数或局部变量类型必须为Lambda对应的接口类型;
- PS: 有且近日有一个抽象方法的接口称为函数式接口。
学习产出:
1、 线程池
package mypackage.day14.demo01;
public class RunnableAchieve implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
package mypackage.day14.demo01;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPool {
public static void main(String[] args) {
ExecutorService pool = Executors.newFixedThreadPool(3);
RunnableAchieve achieve = new RunnableAchieve();
pool.submit(achieve);
pool.submit(achieve);
pool.submit(achieve);
pool.shutdown();
}
}
2、无参无返回的lambda表达式
package mypackage.day14.demo02;
public interface Cook {
public abstract void makeFood();
}
package mypackage.day14.demo02;
//无参无返回
public class LambdaCook {
public static void main(String[] args) {
System.out.println("=====匿名内部类=========");
invokeCook(new Cook() {
@Override
public void makeFood() {
System.out.println("开始做饭!!!");
}
});
System.out.println("=====Lambda表达式=======");
invokeCook(()->{
System.out.println("开始做饭!!!");
});
}
public static void invokeCook(Cook cook){
cook.makeFood();
}
}
3、 有参无返回的lambda表达式
package mypackage.day14.demo03;
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@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;
}
}
package mypackage.day14.demo03;
//有参无返回
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Comparator;
public class LambdaSort {
public static void main(String[] args) {
Person[] arr = {
new Person("Jim",22),
new Person("Tom",18),
new Person("Mary",29)
};
// Arrays.sort(arr, new Comparator<Person>() {
// @Override
// public int compare(Person o1, Person o2) {
// return o1.getAge()-o2.getAge();
// }
// });
Arrays.sort(arr,(o1, o2) -> {
return o1.getAge()-o2.getAge();
});
for (Person person : arr) {
System.out.println(person);
}
}
}
4、 有参有返回的lambda表达式
package mypackage.day14.demo04;
public interface Calculator {
public abstract int calc(int a, int b);
}
package mypackage.day14.demo04;
//有参有返回
public class LambdaCalculator {
public static void main(String[] args) {
invoke(2, 3, new Calculator() {
@Override
public int calc(int a, int b) {
return a+b;
}
});
invoke(3,4,(int a, int b)->{
return a+b;
});
}
public static void invoke(int a, int b, Calculator calculator){
int sum = calculator.calc(a,b);
System.out.println(sum);
}
}