您的位置:首页 > 其它

多线程通信【生产消费案例】

2017-07-20 21:02 281 查看

介绍:

在多线程环境下,虽然,我们能够让两个线程安全的隔离的执行锁范围内所包含的代码块,但是还有个问题就是一个线程会在一个时间段类执行代码块很多次,但是我们的需求是让一个线程锁范围所包含的代码块在抢到CPU执行片后只执行一次,我们该怎么实现呢???

等待和激活。

那么在这种情况下,就非常需要两个东西了:等待和激活。

notify();
wait();

注意:在wait()后,再次通过notify()激活线程时,该线程的执行还是从wait()后第一行开始执行。

你知道wait()和sleep()方法的区别吗??
答:wait()会释放锁,而sleep()不会释放锁。


资源类:

/**
* Created by FireLang on 2017-07-20.
*/
public class Student {
private String mName;
private Integer mAge;
private boolean mIsEat = false;

public String getName() {
return mName;
}

public boolean isEat() {
return mIsEat;
}

public void setEat(boolean eat) {
mIsEat = eat;
}

public void setName(String name) {
mName = name;
}

public Integer getAge() {
return mAge;
}

public void setAge(Integer age) {
mAge = age;
}
}


生产者:

/**
* Created by FireLang on 2017-07-20.
*/
public class SetStudent implements Runnable {
private Student mStudent;
private int mNum = 0;

public SetStudent(Student student) {
mStudent = student;
}

@Override
public void run() {
while (true) {
synchronized (mStudent) {
if (mStudent.isEat()) {
try {
mStudent.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

if (mNum % 2 == 0) {
mStudent.setName("Joy");
mStudent.setAge(18);
} else {
mStudent.setName("FireLang");
mStudent.setAge(19);
}
mNum++;

mStudent.setEat(true);
mStudent.notify();
}
}
}

}


消费者:

/**
* Created by FireLang on 2017-07-20.
*/
public class GetStudent implements Runnable {
private Student mStudent;

public GetStudent(Student student) {
mStudent = student;
}

@Override
public void run() {
while (true) {
synchronized (mStudent) {
if (!mStudent.isEat()) {
try {
mStudent.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

System.out.println(mStudent.getName() + "--->" + mStudent.getAge());

mStudent.setEat(false);
mStudent.notify();
}
}
}
}


测试类:

/**
* Created by FireLang on 2017-07-20.
*/
public class StudentDemo {
public static void main(String[] args) {
Student student = new Student();

GetStudent getStudent = new GetStudent(student);
SetStudent setStudent = new SetStudent(student);

Thread t1 = new Thread(getStudent);
Thread t2 = new Thread(setStudent);

t1.start();
t2.start();
}
}


最后的输出就是,你一次,我一次,你一次,我一次。

下面就涉及到线程的执行状况了。

线程的状态转换图及常见执行情况

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐