各位小伙伴们大家好,在之前的文章中,小编陆陆续续讲了很多关于线程还有等待唤醒机制的一些知识,这次小编要讲的是等待唤醒机制的代码实现。

就用快递员送快递,我们取快递来举例,首先要进行需求分析。主要有两个线程,快递员线程和用户线程,一个送快递,一个拿快递。

我们首先需要定义一个快递类,代码如下:

//定义一个快递类
public class FastEmail {
String ExpressOrderNo;//快递订单号
String ExpressType;//快递类型
//有没有快递:有true,没有false,设置初始值为false
boolean flag=false;
}
//快递员类
public class Expressman extends Thread{
//1.需要在成员位置创建一个快递变量
private FastEmail fe;
//2.使用带参构造方法,为这个包子变量赋值
public Expressman(FastEmail fe) {
this.fe=fe;
}
//设置线程任务(run):送快递
public void run() {
//定义一个变量
int count=0;
while(true) {
//必须使用同步技术保证两个线程只能有一个在执行。
synchronized(fe) {
//对快递状态进行判断
if(fe.flag==true) {
//快递员调用wait方法等待
try {
fe.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//被唤醒后执行,快递员送快递
if(count%2==0) {
fe.ExpressType="中通";
fe.ExpressOrderNo="12345";
}else {
fe.ExpressType="申通";
fe.ExpressOrderNo="67890";
}
count++;
System.out.println("快递员正在配送:"+fe.ExpressType+fe.ExpressOrderNo+"快递");
//配送快递需要10s
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//修改状态为已送达
fe.flag=true;
//唤醒客户取件
fe.notify();
System.out.println("快递"+fe.ExpressType+fe.ExpressOrderNo+"已送达"+","+"请取件");
}
}}
}


//用户类是一个线程类,可以继承Thread
public class User extends Thread{
//在成员位置创建一个快递变量
private FastEmail fe;
//使用带参构造方法,为这个快递变量赋值
public User(FastEmail fe) {
this.fe=fe;
}
//设置线程任务(run):取快递
public void run() {
while(true) {
//使用同步技术保证两个线程只能有一个在执行
synchronized(fe) {
//对快递的状态进行判断
if(fe.flag==false) {
//用户进入等待状态
try {
fe.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//被唤醒之后执行的代码
System.out.println("用户取快递"+","+fe.ExpressType+fe.ExpressOrderNo);
//快递已取,修改转态为false
fe.flag=false;
//用户唤醒快递员线程,送快递
fe.notify();
System.out.println("快递已取"+","+fe.ExpressType+fe.ExpressOrderNo);
System.out.println("-----------------------------");
}}
}
}

/*测试类:

* 包含main方法,程序执行的入口,启动程序
* 创建快递对象
* 创建快递员线程,开启线程,送快递
* 创建用户线程,开启,取快递*/
public class Text {
public static void main(String[] args) {
//创建快递对象
FastEmail fe=new FastEmail();
//创建外卖员线程,开启,送外卖
new Expressman(fe).start();
new User(fe).start();
}
}

这个案例分为三个步骤,快递类,快递员类(是一个线程类,可以继承Thread),用户类与快递员类一样,也是一个线程类,最后是测试类,调用这些线程。

快递类主要是设置快递的属性,快递员类还有用户类就需要根据快递的状态来进行等待唤醒机制的操作,实现线程之间的通信有效利用快递这个资源。

大家要创建快递员线程还有用户线程时要注意:

快递员线程和用线程是通信关系Java之线程间的通信与等待唤醒机制,必须使用同步技术保证两个线程只能执行一个。锁对象必须保证唯一,可以使用快递对象作为锁对象。这样的话,快递员类和用户类就需要把快递对象作为参数传递进来。需要在成员位置创建一个快递变量,使用带参数构造方法,为这个快递变量赋值。关于等待唤醒机制的代码实现,简单一点说,等待唤醒机制其实就是线程之间的协作,比较重要的还是案例分析。小编就先说到这里,如果不懂的话,根据代码再仔细分析一下,或者结合小编之前的文章来理解。希望这篇文章可以帮到大家,也欢迎各位小伙伴补充和纠错。