wait() : 让当前线程进入无限等待的状态
notify() : 随机唤醒一条等待的线程
notifyAll() : 唤醒所有等待的线程
wait()和notify()方法的特点:
- 两个方法必须在同步中.
- 两个方法必须使用锁对象来调用
- 两个方法是定义在Object类中
package com.itheima._02waitnotify.demo02;
/**
* 生产者线程
*/
public class Producer extends Thread {
// 将BaoZi作为成员变量, 然后通过构造方法赋值
private BaoZi baoZi;
public Producer(BaoZi baoZi) {
this.baoZi = baoZi;
}
@Override
public void run() {
// 无限循环
while (true) {
// 同步代码块
synchronized (baoZi) {
// 如果有包子
if (baoZi.isHaveBaoZi) {
// 等待
try {
baoZi.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 代码执行到这里, 说明一定没有包子
try {
System.out.println("【生产者】生产者正在生产包子... ... ");
Thread.sleep(1000);
System.out.println("【生产者】包子做好了, 消费者快来吃!");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 有包子了!!!
baoZi.isHaveBaoZi = true;
// 唤醒消费者来吃包子
baoZi.notify();
}
}
}
}
package com.itheima._02waitnotify.demo02;
/**
* 消费者线程
*/
public class Consumer extends Thread {
private BaoZi baoZi;
public Consumer(BaoZi baoZi) {
this.baoZi = baoZi;
}
@Override
public void run() {
// 无限循环
while (true) {
// 同步代码块
synchronized (baoZi) {
// 如果没有包子
if (!baoZi.isHaveBaoZi) {
// 等待
try {
baoZi.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
// 代码执行到这里, 说明一定有包子
System.out.println("【消费者】消费者正在吃包子... ... ");
Thread.sleep(1000);
System.out.println("【消费者】包子吃完了, 生产者快来做!");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 包子没了
baoZi.isHaveBaoZi = false;
// 唤醒生产者来做包子
baoZi.notify();
}
}
}
}
package com.itheima._02waitnotify.demo02;
/**
* 这是一个包子类,
* 类中有是否有包子的属性
*
* 这个类的对象会当做锁对象
*/
public class BaoZi {
/**
* 是否有包子
* true: 有
* false : 没有
*/
boolean isHaveBaoZi = false;
}
package com.itheima._02waitnotify.demo02;
public class Test {
public static void main(String[] args) {
BaoZi baoZi = new BaoZi();
Producer p = new Producer(baoZi);
Consumer c = new Consumer(baoZi);
p.start();
c.start();
}
}
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("开启了一条新线程!~");
}
}).start(); // 参数中需要传入Runnable接口, 那么实际传入的应该是该接口的实现类对象
// 不得不创建一个类, 实现Runnable接口
// 为了不创建一个类, 所以使用匿名内部类
// 不得不重写run方法
// 不得不写出跟接口中的run方法, 方法名相同, 参数列表相同, 返回值类型也相同
// 最终我真正需要的代码其实就是方法体中的代码
new Thread(() -> System.out.println("开启了一条新线程!~")).start();
思想上的转变
() : 一些参数
-> : 一个箭头
{} : 一段代码
() -> {} : 将小括号中的参数, 给大括号中的代码使用
如何将匿名内部类转换成Lambda表达式
需求
接口
public interface Cook {
void makeFood();
}
package com.itheima._04lambda.demo02;
public class Demo02_无参无返回的lambda {
public static void main(String[] args) {
// 我们要做的是方法的调用!!!
// 匿名内部类
invokeCook(new Cook() {
@Override
public void makeFood() {
System.out.println("吃饭啦!");
}
});
// lambda的标准格式
invokeCook(() -> {
System.out.println("吃饭啦!");
});
// lambda的省略格式
invokeCook(() -> System.out.println("吃饭啦!"));
}
// 如果方法的参数列表是接口, 那么实际传入的是它的实现类对象
private static void invokeCook(Cook cook) {
cook.makeFood();
}
}
public interface MyInter {
String fun();
}
package com.itheima._04lambda.demo03;
public class Demo03_无参有返回的lambda {
public static void main(String[] args) {
// 我们要做的, 方法的调用
// 匿名内部类
method(new MyInter() {
@Override
public String fun() {
return "HelloLambda";
}
});
// lambda的标准格式
method(() -> {
return "HelloLambda";
});
// lambda的省略格式
method(() -> "HelloLambda");
}
// 模拟方法, 让接口作为方法的参数
private static void method(MyInter mi) {
System.out.println(mi.fun());
}
}
public interface Printable {
void print(String s);
}
package com.itheima._04lambda.demo04;
public class Demo04_有参无返回的lambda {
public static void main(String[] args) {
// 调用方法
// 匿名内部类
printString(new Printable() {
@Override
public void print(String s) {
System.out.println(s);
}
});
// lambda的标准格式
printString((String s) -> {
System.out.println(s);
});
// lambda的省略格式
printString(s -> System.out.println(s));
}
// 模拟方法, 参数列表是接口
private static void printString(Printable p) {
p.print("HelloLambda");
}
}
public interface Calculator {
int calc(int a, int b);
}
package com.itheima._04lambda.demo05;
public class Demo05_有参有返回的lambda {
public static void main(String[] args) {
// 匿名内部类
invokeCalc(120, 130, new Calculator() {
@Override
public int calc(int a, int b) {
return a + b;
}
});
// lambda的标准格式
invokeCalc(234, 432,(int a, int b) -> {
return a + b;
});
// lambda的省略格式
invokeCalc(234, 432, (a, b) -> a + b);
}
private static void invokeCalc(int a, int b, Calculator calculator) {
int result = calculator.calc(a, b);
System.out.println("结果是:" + result);
}
}
Runnable
package com.itheima._04lambda.demo06;
public class Demo06_Runnable {
public static void main(String[] args) {
// 匿名内部类
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("新线程11");
}
}).start();
// lambda的标准格式
new Thread(() -> {
System.out.println("新线程22");
}).start();
// lambda的省略格式
new Thread(() -> System.out.println("新线程22")).start();
}
}
Comparator
package com.itheima._04lambda.demo07;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class Demo07_Comparator {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
// 添加元素
Collections.addAll(list, 5, 2, 6, 3, 4, 8, 7, 9, 1);
// 排序, 降序
// 匿名内部类
/*Collections.sort(list, new Comparator() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});*/
// lambda的标准格式
/*Collections.sort(list, (Integer o1, Integer o2) -> {
return o2 - o1;
});*/
// lambda的省略格式
Collections.sort(list, (o1, o2) -> o2 - o1);
// Collections.sort(list, Comparator.reverseOrder());
System.out.println(list);
}
}
省略规则