线程交互现象
线程交互现象
小明对自家的狗子有个规定,就是在狗狗还没吃完的时候,可以继续给他加饭
不好的解决方式
狗狗感觉一千年没吃饭了,狼吞虎咽起来,最后饭只剩下最后一点点,吃饭线程中使用while循环判断是否是1,如果是1那么就一直循环,知道加饭又重新回到了起点,这虽然是狗狗能够吃的更多,那么狗狗也会长得太胖了,太胖对狗狗健康有威胁,所以是一个不好的解决方式。
package multiThread2; public class test { public static void main(String[] args) { Animal a = new Animal("大黄", 3, 10); Thread t1 = new Thread(){ @Override public void run() { while (true){ while (a.getFood()==1){ continue; } a.eatFood(); System.out.println(a.getName()+"吃饭,剩余"+a.getFood()); try { Thread.sleep(1); }catch (InterruptedException e){ e.printStackTrace(); } } } }; t1.start(); Thread t2 = new Thread(){ @Override public void run() { while (true){ a.addFood(); System.out.println(a.getName()+"加饭,剩余"+a.getFood()); try { Thread.sleep(100);//这里注意,时间必须比上面多,不然无法看见饭剩下1 }catch (InterruptedException e){ e.printStackTrace(); } } } }; t2.start(); } }12345678910111213141516171819202122232425262728293031323334353637383940
package multiThread2;
public class Animal{
private String name;
private int year;
Animal(){}
private int food;
public Animal(String name,int year,int food){
this.name = name;
this.year = year;
this.food = food;
}
@Override
public String toString() {
return "姓名:"+ name + ",年龄:" + year + ",来干饭了,还剩"+ food + "个食物";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getFood() {
return food;
}
public void setFood(int food) {
this.food = food;
}
public synchronized void eatFood(){
synchronized(this) {
this.food--;
}
}
public void addFood(){
synchronized (this) {
this.food++;
}
}
}
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
使用wait和notify进行线程交互
在Animal类中,eatfood方法,当food==1时,执行this.wait()
this.wait()指的是暂停执行,释放占有
进入eatfood方法,使用this.wait()可以让吃食物线程临时释放对this的占有,这样就有机会进入addfood方法了
addfood:增加食物之后,执行this.notify
this.notify表示通知等待this的线程,可以苏醒过来了。等待在this的线程,是吃饭过程。一旦addfood()结束,加食物线程释放了this,吃食物线程,重新占有this,执行后面的吃食物工作。 package multiThread2; public class Animal{ private String name; private int year; Animal(){} private int food; public Animal(String name,int year,int food){ this.name = name; this.year = year; this.food = food; } @Override public String toString() { return "姓名:"+ name + ",年龄:" + year + ",来干饭了,还剩"+ food + "个食物"; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getYear() { return year; } public void setYear(int year) { this.year = year; } public int getFood() { return food; } public void setFood(int food) { this.food = food; } public synchronized void eatFood(){ if(food==1) { try{ this.wait(); }catch (InterruptedException e){ e.printStackTrace(); } this.food--; } } public synchronized void addFood(){ this.food++; this.notify(); } }1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
package multiThread2;
public class test {
public static void main(String[] args) {
Animal a = new Animal("大黄", 3, 10);
Thread t1 = new Thread(){
@Override
public void run() {
while (true){
// while (a.getFood()==1){
// continue;
// }
a.eatFood();
System.out.println(a.getName()+"吃饭,剩余"+a.getFood());
try {
Thread.sleep(1);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
};
t1.start();
Thread t2 = new Thread(){
@Override
public void run() {
while (true){
a.addFood();
System.out.println(a.getName()+"加饭,剩余"+a.getFood());
try {
Thread.sleep(100);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
};
t2.start();
}
}
12345678910111213141516171819202122232425262728293031323334353637383940
这里需要强调的是,wait方法和notify方法,并不是Thread线程上的方法,它们是Object上的方法。
因为所有的Object都可以被用来作为同步对象,所以准确的讲,wait和notify是同步对象上的方法。
wait()的意思是: 让占用了这个同步对象的线程,临时释放当前的占用,并且等待。 所以调用wait是有前提条件的,一定是在synchronized块里,否则就会出错。
notify() 的意思是,通知一个等待在这个同步对象上的线程,你可以苏醒过来了,有机会重新占用当前对象了。
notifyAll() 的意思是,通知所有的等待在这个同步对象上的线程,你们可以苏醒过来了,有机会重新占用当前对象了。Ongwu博客 版权声明:以上内容未经允许不得转载!授权事宜或对内容有异议或投诉,请联系站长,将尽快回复您,谢谢合作!