java线程 wait notify

a455295165 2014-09-24 05:34:05
源码如下:

public class TakeAndPour {
public static void main(String args[]) {
WaterTaking wt = new WaterTaking();
WaterPouring wp = new WaterPouring();
Thread t1 = new Thread(wt, "Xiaohao");
Thread t2 = new Thread(wp, "doubi");
t1.start();
t2.start();
}
}
class Tank {
private static int count = 10; // 缸里原有的水
//private static int max = 5;
private static boolean flag = true; //防止同时取水、 倒入水
public void takeWater() {
synchronized (this) {
while (!flag) {
try {
System.out
.println("The tank is being used now");
this.wait();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
flag = false; //同一时刻只允许一个对水缸操作
try {
Thread.sleep(800);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
count--;
System.out.println(flag+" "+Thread.currentThread().getName()
+ " take out some water" + " now water remain " + count);


flag = true;
this.notifyAll(); //操作完了就把flag置为true,并唤醒线程,这里使用notify()一样。

}
}
public void pourWater() {
synchronized (this) {
flag = false;
while (!flag) {
try {
System.out
.println("the tank is being used");
this.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
try {
Thread.sleep(800);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
count++;
System.out.println(flag+" "+Thread.currentThread().getName()
+ " pour in some water" + " now water remain " + count);
flag = true;
this.notifyAll();

}
}
}

class WaterTaking implements Runnable {
Tank t = new Tank();

public void run() {
while(true){
t.takeWater();
}
}
}
class WaterPouring implements Runnable {
Tank t = new Tank();

public void run() {
while(true){
t.pourWater();
}
}
}


但是 现在的结果出现了问题,打印如下:
the tank is being used, or the tank is full of water.
false Xiaohao take out some water now water remain 9
false Xiaohao take out some water now water remain 8
false Xiaohao take out some water now water remain 7
false Xiaohao take out some water now water remain 6
false Xiaohao take out some water now water remain 5
false Xiaohao take out some water now water remain 4
false Xiaohao take out some water now water remain 3
.......
倒入水的线程,第一下进去就被卡住了,全是取水的线程。求各位帮下忙分析下问题所在,谢了!
...全文
114 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 4 楼 xsm_lyf 的回复:
[quote=引用 3 楼 a455295165 的回复:] [quote=引用 1 楼 xsm_lyf 的回复:] 同步就是许多线程同时用一个资源啥的哦,一个在用别的就要等,异步就相反了,可以不用等待 先搞清楚同步异步的含义吧 概念混淆 还有 你这个水可以放城负数也是够了 count的值都没有判断下 修改flag 来控制
恩,确实可以放成负数,但是现在还处于第一阶段,就出错了,本来想先试一下,以后再完善的。。 缸不是同一个资源么,倒水、取水的时候 不是就将 flag设置为 false了么,然后就让别的线程等待了啊[/quote]
package test_my;

public class TakeAndPour {
	
	public static void main(String args[]) {
			WaterTaking wt = new WaterTaking();
			WaterPouring wp = new WaterPouring();
			Thread t1 = new Thread(wt, "Xiaohao");
			Thread t2 = new Thread(wp, "doubi");
			t1.start();
			t2.start();
	}
}
class Tank {
	private static int count = 10; // 缸里原有的水
	//private static int max = 5;
	//防止同时取水、 倒入水
	public static boolean flag = false; 
	public void takeWater() {
		synchronized (this) {
			
		
			//同一时刻只允许一个对水缸操作
		
			if(count>0){
			count--;
			System.out.println(flag+" "+Thread.currentThread().getName()
					+ " take out some water" + " now water remain " + count);
			}
		
	
			 
			this.notifyAll(); //操作完了就把flag置为true,并唤醒线程,这里使用notify()一样。
			
		}
	}
	public void pourWater() {
		
		synchronized (this) {		
			
		
		
			count++;
			System.out.println(flag+" "+Thread.currentThread().getName()
					+ " pour in some water" + " now water remain " + count);
	
		
			this.notifyAll();
			
		}
	}
	
}

class WaterTaking implements Runnable {
	Tank t = new Tank();
	int m=10;
	public void run() {
		while(m-->0){
		t.takeWater();
		}
	}
}
class WaterPouring implements Runnable {
	Tank t = new Tank();
	int m=10;
	public void run() {
		while(m-->0){
		t.pourWater();
		}
	}
}

[/quote] 你这个全局变量有问题
  • 打赏
  • 举报
回复
引用 3 楼 a455295165 的回复:
[quote=引用 1 楼 xsm_lyf 的回复:] 同步就是许多线程同时用一个资源啥的哦,一个在用别的就要等,异步就相反了,可以不用等待 先搞清楚同步异步的含义吧 概念混淆 还有 你这个水可以放城负数也是够了 count的值都没有判断下 修改flag 来控制
恩,确实可以放成负数,但是现在还处于第一阶段,就出错了,本来想先试一下,以后再完善的。。 缸不是同一个资源么,倒水、取水的时候 不是就将 flag设置为 false了么,然后就让别的线程等待了啊[/quote]
package test_my;

public class TakeAndPour {
	
	public static void main(String args[]) {
			WaterTaking wt = new WaterTaking();
			WaterPouring wp = new WaterPouring();
			Thread t1 = new Thread(wt, "Xiaohao");
			Thread t2 = new Thread(wp, "doubi");
			t1.start();
			t2.start();
	}
}
class Tank {
	private static int count = 10; // 缸里原有的水
	//private static int max = 5;
	//防止同时取水、 倒入水
	public static boolean flag = false; 
	public void takeWater() {
		synchronized (this) {
			
		
			//同一时刻只允许一个对水缸操作
		
			if(count>0){
			count--;
			System.out.println(flag+" "+Thread.currentThread().getName()
					+ " take out some water" + " now water remain " + count);
			}
		
	
			 
			this.notifyAll(); //操作完了就把flag置为true,并唤醒线程,这里使用notify()一样。
			
		}
	}
	public void pourWater() {
		
		synchronized (this) {		
			
		
		
			count++;
			System.out.println(flag+" "+Thread.currentThread().getName()
					+ " pour in some water" + " now water remain " + count);
	
		
			this.notifyAll();
			
		}
	}
	
}

class WaterTaking implements Runnable {
	Tank t = new Tank();
	int m=10;
	public void run() {
		while(m-->0){
		t.takeWater();
		}
	}
}
class WaterPouring implements Runnable {
	Tank t = new Tank();
	int m=10;
	public void run() {
		while(m-->0){
		t.pourWater();
		}
	}
}

a455295165 2014-09-25
  • 打赏
  • 举报
回复
引用 1 楼 xsm_lyf 的回复:
同步就是许多线程同时用一个资源啥的哦,一个在用别的就要等,异步就相反了,可以不用等待 先搞清楚同步异步的含义吧 概念混淆 还有 你这个水可以放城负数也是够了 count的值都没有判断下 修改flag 来控制
恩,确实可以放成负数,但是现在还处于第一阶段,就出错了,本来想先试一下,以后再完善的。。 缸不是同一个资源么,倒水、取水的时候 不是就将 flag设置为 false了么,然后就让别的线程等待了啊
a455295165 2014-09-25
  • 打赏
  • 举报
回复
我找到原因了,我用的synchronized (this) 阻塞和唤醒也是用的 this.wait this.notify 但是显然是使用的两个不同的对象来调用的,所以this.notify是不能唤醒另一个被阻塞的线程的 我在Tank类里加了一个静态变量 private static Object ob = new Object(); 然后 把this换成ob 由于是静态全局变量所以ob都是同一个,于是就可以相互唤醒了。 最后把max,min也设置好了,程序完美运行。
  • 打赏
  • 举报
回复
思路不清
  • 打赏
  • 举报
回复
同步就是许多线程同时用一个资源啥的哦,一个在用别的就要等,异步就相反了,可以不用等待 先搞清楚同步异步的含义吧 概念混淆 还有 你这个水可以放城负数也是够了 count的值都没有判断下 修改flag 来控制

50,526

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧