等待唤醒机制(Wait和Notify)
public class TestDemo01 {
public static void main(String[] args) throws InterruptedException {
//1.让线程进入无限等待
//锁对象
Object obj = new Object();
//线程1
new Thread(new Runnable() {
@Override
public void run() {
//1.抢到锁
synchronized (obj) {
System.out.println("线程1抢到锁对象了,准备进入无限等待....");
//2.调用锁对象的wait方法
try {
obj.wait();//3.自动释放obj锁对象
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程1继续执行...");
}
}
}).start();
//线程2
new Thread(new Runnable() {
@Override
public void run() {
//1.抢到锁
synchronized (obj) {
System.out.println("线程2也抢到锁对象了,准备进入无限等待....");
//2.调用锁对象的wait方法
try {
obj.wait();//3.自动释放obj锁对象
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程2继续执行...");
}
}
}).start();
//这个循环目的就是为了线程1先执行,抢到锁对象进入无限等待
for (int i = 0; i < 10; i++) {
Thread.sleep(500);
System.out.println(i);
}
//线程3
new Thread(new Runnable() {
@Override
public void run() {
//1.持有锁,并且必须也是obj
synchronized (obj) {
System.out.println("线程3抢到锁对象了,准备唤醒线程...");
//2.调用锁对象的notify方法
obj.notify(); //但是锁对象并没有释放
//以下代码必须使用完毕,释放锁对象,线程1才能再次持有锁对象,才能往下执行
// for (int i = 0; i < 100; i++) {
// System.out.println("线程3..."+i);
// }
}
}
}).start();
}
}
生产者与消费者问题(代码演示)
创建两个线程,生产者线程负责做包子,消费者线程负责吃包子,要求两个线程交替执行
public class TestDemo {
public static void main(String[] args) {
//1.集合
ArrayList<String> arr = new ArrayList<String>();
arr.add("猪肉大葱包子");
Object obj = new Object();
//2.创建两个线程
//生产者线程
new Thread(new Runnable() {
@Override
public void run() {
while (true){
synchronized (obj){
//判断
if (arr.size() == 1) {
//有包子,那么生产者线程无限等待
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//没有包子,做包子
arr.add("牛肉大葱包子");
System.out.println("吃货,包子做好了....");
//唤醒消费者
obj.notify();
}
}
}
}).start();
//消费者线程
new Thread(new Runnable() {
@Override
public void run() {
while (true){
synchronized (obj){
//判断
if (arr.size() == 0) {
//如果没有包子
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果有包子,吃包子
String remove = arr.remove(0);
System.out.println("你做的"+remove+"真好吃...");
//唤醒生产者线程
obj.notify();
}
}
}
}).start();
}
}
定时器
1. 什么是定时器
我们可以想象为闹钟,在指定的时间做指定的事情!!
2. 定时器Timer的使用
- 构造方法
public Timer():构造一个定时器
- 成员方法
public void schedule(TimerTask task,Date time);
public void schedule(TimerTask task,long millis);
public void schedule(TimerTask task,Date time,long period);
public void schedule(TimerTask task,long millis,long period);
- 案例演示
public class TestTimerDemo {
public static void main(String[] args) {
//1.创建定时器
Timer timer = new Timer();
//2.布置任务
//一次性定时器
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("时间到了下课...");
}
},5000);
Calendar cc = Calendar.getInstance();
cc.add(Calendar.SECOND,5);
Date time = cc.getTime();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("时间到了下课...");
}
},time);
//周期定时器
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("时间到了下课...");
}
},5000,2000);
Calendar cc1 = Calendar.getInstance();
cc1.add(Calendar.SECOND,5);
Date time1 = cc1.getTime();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("时间到了下课...");
}
},time1,1000);
}
}