当前位置: 代码迷 >> J2SE >> 代码没有出错运行不了高手帮忙看
  详细解决方案

代码没有出错运行不了高手帮忙看

热度:94   发布时间:2016-04-23 20:33:17.0
代码没出错运行不了高手帮忙看
class Res{
private boolean flag=false;
private String name;
private int bianhao=1;
public synchronized void set(String name){
while(flag){
try{
wait();
}
catch(Exception e){

}
this.name=name+"......"+bianhao++;
System.out.println(Thread.currentThread().getName()+"......"+this.name);
flag=true;
this.notifyAll();
}
}
public synchronized void out(){
while(!flag){
try{
wait();
}
catch(Exception e){

}
System.out.println("consume:"+name+"........."+bianhao++);
flag=false;
this.notifyAll();
}
}
}
class Produce implements Runnable{
Res r;
Produce(Res r){
this.r=r;
}
public void run(){
while(true)
r.set("商品");
}
}
class Sale implements Runnable{
Res r;
Sale(Res r){
this.r=r;
}
public void run(){
while(true)
r.out();
}
}
public class lx {
public static void main(String[] args){
Res r=new Res();
Produce pr=new Produce(r);
Sale sal=new Sale(r);
Thread t1=new Thread(pr);
Thread t2=new Thread(pr);
Thread t3=new Thread(sal);
Thread t4=new Thread(sal);
t1.start();
t2.start();
t3.start();
t4.start();
}
}哪里出错了找了好久实在不懂 求高手帮忙看看  万分感谢!!!!!!!! 另外这个代码中produce和sale中创建的Res r后  用加了一个构造方法用来传递Res对象  但是在这个代码中不构建我感觉也没影响吧,给我分析下  谢谢  

------解决方案--------------------

class Res {
private boolean flag = false;
private String name;
private int bianhao = 1;

public synchronized void set(String name) {
while (flag) {
try {
wait();
} catch (Exception e) {

}
this.name = name + "......" + bianhao++;
System.out.println(Thread.currentThread().getName() + "......"
+ this.name);
flag = true;
this.notifyAll();
}
}

public synchronized void out() {
while (!flag) {
try {
wait();
} catch (Exception e) {

}
System.out.println("consume:" + name + "........." + bianhao++);
flag = false;
this.notifyAll();
}
}
}

class Produce implements Runnable {
Res r;

Produce(Res r) {
this.r = r;
}

public void run() {
while (true)
r.set("商品");
}
}

class Sale implements Runnable {
Res r;

Sale(Res r) {
this.r = r;
}

public void run() {
while (true)
r.out();
}
}

class lx {
public static void main(String[] args) {
Res r = new Res();
Produce pr = new Produce(r);
Sale sal = new Sale(r);
Thread t1 = new Thread(pr);
Thread t2 = new Thread(pr);
Thread t3 = new Thread(sal);
Thread t4 = new Thread(sal);
t1.start();
t2.start();
t3.start();
t4.start();
}
}


------解决方案--------------------
引用:
你这是多线程中生产者和消费者吧
1、在Sale和Produce类的run()方法都中已经有了一个while循环了,而你又在Res的两个同步方法中又加了一个while循环,假如你的t1线程进入了set()方法的中的while循环之后,他一直死循环出不来的,你t2线程是没法进入set()中去的
以你Res类中set()方法为例说明,如下:
public synchronized void set(String name)
{
while (flag)//当flag为true时,假设t1进入此方法
{
try
{
wait();//让t1进入res的等待队列,t1阻塞中。。。
} catch (Exception e)
{

}
//到这一步,t1被其他消费者线程唤醒,执行一下代码(flag已经被消费者线程设为false了)
this.name = name + "......" + bianhao++;
System.out.println(Thread.currentThread().getName() + "......"
+ this.name);
flag = true; //flag再次被设为true
this.notifyAll();//唤醒其它线程,再次进入while循环,t1就出不了这个while循环
}
}

因此,你应该将set()和out()方法中while改为if,以下代码仅供参考,以set()方法为例:
public synchronized void set(String name)
{
if (flag)
{
try
{
wait();
} catch (Exception e)
{

}
}
this.name = name + "......" + bianhao++;
System.out.println(Thread.currentThread().getName() + "......"
+ this.name);
flag = true;
this.notifyAll();
}

2、如上,将Res类中set()和out()方法中的while改为if之后,你的程序就能跑起来啦


3.纠正下:因为flag的初始状态为flase,你在set()中用while(flag)来判断的话,while中代码始终得不到执行,flag也就始终为false!所以当你在out()方法中进入while循环之后,调用wait()阻塞的那些线程永远不会被唤醒,你的程序肯定运行不起来!
当然你这里用while来判断flag貌似也行,但是你也需要将try{}catch{}后面的代码拿到while循环外面来
  相关解决方案