当需要多个线程之间共同完成同一个任务,并且希望它们有规律的执行,此时需要线程之间的协调通信
public class BaoZiPu extends Thread {
private BaoZi bz;
public BaoZiPu(BaoZi bz) {
this.bz = bz;
}
@Override
public void run() {
int count = 0;
while (true) {
synchronized (bz) {
if (bz.flag == true) {
try {
bz.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (count % 2 == 0) {
bz.pi = "薄皮";
bz.xian = "三鲜馅";
} else {
bz.pi = "冰皮";
bz.xian = "牛肉大葱馅";
}
count++;
System.out.println("包子铺正在生产" + bz.pi + bz.xian + "包子");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
bz.flag = true;
bz.notify();
System.out.println("包子铺已经生产好了:" + bz.pi + bz.xian + "包子,吃货可以来吃了");
}
}
}
}
public class ChiHuo extends Thread{
private BaoZi bz;
public ChiHuo(BaoZi bz){
this.bz=bz;
}
@Override
public void run() {
while(true){
synchronized (bz){
if (bz.flag == false) {
try{
bz.wait();
}catch (InterruptedException e){
e.printStackTrace();
}
}
System.out.println("吃货正在吃:"+bz.pi+bz.xian+"的包子");
bz.flag=false;
bz.notify();
System.out.println("吃货吃完了:"+bz.pi+bz.xian+"的包子,包子铺开始生产包子");
}
}
}
}
public class BBC {
public static void main(String[] args) {
BaoZi bz=new BaoZi();
new BaoZiPu(bz).start();
new ChiHuo(bz).start();
}
}
/*运行结果:
包子铺正在生产薄皮三鲜馅包子
包子铺已经生产好了:薄皮三鲜馅包子,吃货可以来吃了
吃货正在吃:薄皮三鲜馅的包子
吃货吃完了:薄皮三鲜馅的包子,包子铺开始生产包子
包子铺正在生产冰皮牛肉大葱馅包子
包子铺已经生产好了:冰皮牛肉大葱馅包子,吃货可以来吃了
吃货正在吃:冰皮牛肉大葱馅的包子
吃货吃完了:冰皮牛肉大葱馅的包子,包子铺开始生产包子*/
Timed Waiting计时等待
Blocked锁阻状态
Waiting无限等待
线程池的概念和原理
容纳一个或多个线程的容器,其中的线程可以多次反复使用,省去了频繁创建线程的麻烦
lambda表达式标准格式
1.一些参数
2.一个箭头
3.一段代码
格式:(参数列表)->{一些重写方法代码}
():接口中抽象方法的参数列表,没有参数就空着;有参数就写出参数,多个参数用逗号隔开
->:传递的意思,把参数传递给方法体{}
{}:重写接口的抽象方法的方法体
import java.util.Arrays;
import java.util.Comparator;
public class DemoPerson {
public static void main(String[] args) {
Person[] arr={
new Person("柳岩",28),
new Person("刘亦菲",18),
new Person("李菲儿",20),
};
//使用Lambda表达式简化
Arrays.sort(arr,(Person o1,Person o2) ->{
return o1.getAge()-o2.getAge();
} );
for (Person p: arr
) {
System.out.println(p);
}
}
}
/*运行结果:
Person{name='刘亦菲', age=18}
Person{name='李菲儿', age=20}
Person{name='柳岩', age=28}*/
Lambda优化省略:
1.使用Lambda必须有接口,且要求接口中有且只有一个抽象方法
2.犯法的参数或者局部变量类型必需为Lambda对应的接口类型,才能使用Lambda作为该接口肚饿实例
例如
invokeCalc(a:120,b:130,(int a,int b)->{
return a+b;
});
可以优化为
invokeCalc(a:120,b:130,(a,b)->a+b);