Java线程的等待与唤醒实例
程序员文章站
2022-03-08 18:59:28
...
Java线程的等待与唤醒
生产者和消费者必须使用同步代码块包裹起来,保证等待和唤醒只能有一个执行,同步使用的锁对象必须保证唯一。
Thread中重要方法
void wait() 在其他线程调用此对象的notify()方法或notifyall()方法前,导致当前线程等待。
void notify() 唤醒在此对象监视器上等待的单个线程后,会继续执行wait方法之后的代码。
void notifyAll() 唤醒所有等待线程
void wait(long m)在毫秒结束之后,还没有被notify唤醒,就会自动醒来,线程睡醒进入到Runnable/blocke状态。
void sleep(long m)在毫秒结束之后,线程睡醒进入到Runnable/blocke状态
使用
我们自己创建线程类的子类时,不要忘了写上继承extend。再run()方法中写入线程同步的代码,在客户端调用时,直接调用start方法,默认自动调用run方法的代码。
案例
先写一个产品类。
//产品类
public class Product {
//属性代表产品是否还有
boolean flag=false;
}
生产者类:
//生产者类
public class Producer extends Thread {
private Product pr;
//构适有参构适函教,让产品类实例的对象作为的对象
public Producer(Product pr) {
this.pr = pr;
}
public void run(){
//一直生产该商品
while (true) {
//使用锁对象
synchronized (pr) {
//如果该产品还存在,
if (pr.flag == true) {
try {
//生产者停止生产
pr.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//否则生产者开始生产
System.out.println("生产者正在生产");
try {
//生产时间为5 秒
Thread.sleep(5000);
System.out.println("请等待5秒");
} catch (InterruptedException e) {
e.printStackTrace();
}
//生产完成
pr.flag = true;
//唤醒消费者
pr.notify();
System.out.println("生产者生产完了,消费者开始使用");
}
}
}
}
消费者类:
//消费者类
public class Consumer extends Thread {
private Product pr;
public Consumer(Product pr) {
this.pr = pr;
}
public void run(){
while (true) {
//锁对象
synchronized (pr) {
// 如果产品没有
if (pr.flag == false) {
try {
//则消费者进行等待
pr.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果产品还有,消费者使用产品
System.out.println("消费者正在使用");
//消耗完产品,改变产品属性
pr.flag = false;
//唤醒生产者,等待再次生产产品
pr.notify();
System.out.println("产品已经使用完了,生产者开始生产");
System.out.println("=============================");
}
}
}
}
主函数:
public class test {
public static void main(String[] args) {
//实的化产品
Product pr=new Product();
// 实例化 生产者,并运行run 方法
new Producer(pr).start();
//实例化消费者,并运行run 方法
new Consumer(pr).start();
}
}
因为生产者和消费者都是用的一个锁对象,而锁在同一个线程类中会同行第一个进去该锁的线程,等该进程执行完后会将锁对象归还,下一个进程接着执行,在不同线程类同一个锁对象被设置等待了,由于是一个锁对象,另一个线程类的进程会等待,从而做到了线程类之间的交流。
运行结果
总结
以上就是Java线程的等待与唤醒介绍和练习。