重新对多线程的唤醒机制复习了一下,感觉有点收获.
因为CPU对线程的处理是随机的.因此存在无法按照我们的需求去执行程序的问题.然后唤醒机制算是解决了一些小问题吧.
也就是当线程中之间存在通信(也就是顺序的执行程序)时,这时使用等待唤醒机制可达到按照我们需求的规律执行程序的目的.
注意事项;
1.同步块内使用while()循环,不可使用if()循环;(因为if是按照顺序执行,当notifyALL方法唤醒wait后会处于等待状态,下一次再唤醒时,便不会再去进行if判断,直接向下执行了);
2.需要定义旗帜变量,将共同资源进行调整;
同时,可以联系使用同步方法对线程进行控制(需要注意的是,多个同步方法必须在同一个类里面,其它注意事项参照以上
举例:学生街卖奶茶.当有学生点奶茶,奶茶店便开始生产奶茶.代码如下:
public class Test {
public static void main(String[] args) {
MilkyTea mt = new MilkyTea();
Store st = new Store();
st.mt = mt;
st.start();
Student stu = new Student();
stu.mt = mt;
stu.start();
}
}
public class MilkyTea {
boolean flag = false;
private String taste;
private int capacity;
public MilkyTea() {
}
public MilkyTea(String taste, int capacity) {
this.taste = taste;
this.capacity = capacity;
}
public String getTaste() {
return taste;
}
public void setTaste(String taste) {
this.taste = taste;
}
public int getCapacity() {
return capacity;
}
public void setCapacity(int capacity) {
this.capacity = capacity;
}
}
public class Store extends Thread {
MilkyTea mt;
int count = 0;
public Store() {
}
public Store(MilkyTea mt) {
this.mt = mt;
}
@Override
public void run() {
while (true) {
synchronized (mt) {
if (mt.flag == true) {
try {
mt.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("奶茶店开始制作奶茶");
if (count % 2 == 0) {
mt.setTaste("草莓味");
mt.setCapacity(600);
}
if (count % 2 != 0) {
mt.setTaste("柠檬味");
mt.setCapacity(800);
}
count++;
mt.flag = true;
mt.notifyAll();
}
}
}
}
public class Student extends Thread {
MilkyTea mt;
public Student() {
}
public Student(MilkyTea mt) {
this.mt = mt;
}
@Override
public void run() {
while (true) {
synchronized (mt) {
if (mt.flag == false) {
try {
mt.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("学生在喝奶茶,口味是" + mt.getTaste() + ",容量是" + mt.getCapacity() + "毫升");
mt.flag = false;
mt.notifyAll();
}
}
}
}