黑马程序员技术交流社区

标题: 一个线程问题,不知道出啥问题了? [打印本页]

作者: 刘海源    时间: 2012-7-24 00:09
标题: 一个线程问题,不知道出啥问题了?
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ThreadDemo3 {
        public static void main(String[] args) {
                Resource r=new Resource("鸡腿");
                Input in=new Input(r);
                Output out=new Output(r);
                Thread t1=new Thread(in);
                Thread t2=new Thread(in);
                Thread t3=new Thread(out);
                Thread t4=new Thread(out);
                t1.start();
                t2.start();
                t3.start();
                t4.start();
               
        }

}
class Input implements Runnable
{
        private Resource r;
        Input(Resource r)
        {
                this.r=r;
        }
        public void run()
        {
                while(true)
                {
                        r.set();
                }
        }
}
class Output implements Runnable
{
        private Resource r;
        Output(Resource r)
        {
                this.r=r;
        }
        public void run()
        {
                while(true)
                {
                        r.get();
                }
        }
}
class Resource
{
        private String name;
        private Lock lock=new ReentrantLock();
        private Condition d1=lock.newCondition();
        private Condition d2=lock.newCondition();
        private boolean flag=false;
        public void set()
        {
                lock.lock();
          try
          {
                    while(flag)
                    {try{d1.await();}catch(InterruptedException e){}}
                    System.out.println(Thread.currentThread().getName()+"商品***"+name);
                    flag=false;
                    d2.signalAll();
            
          }finally
          {lock.unlock();}
        }
        public void get()
        {
                lock.lock();
                   try
                  {
                            while(!flag)
                            {try{d1.await();}catch(InterruptedException e){}}
                            System.out.println(Thread.currentThread().getName()+"消费***"+name);
                            flag=true;
                            d1.signalAll();
                   
                  }finally
                  {lock.unlock();}
        }
       
        public Resource(String name)
        {
                this.name=name;
        }
        public String getName() {
                return name;
        }
        public void setName(String name) {
                this.name = name;
        }

}
运行时只有线程1和2跑起来了,3和4不知道出啥问题了跑不起来,自己看着郁闷的要死
作者: 李伟    时间: 2012-7-24 01:36
package cn.itcast.test;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ThreadDemo3 {
        public static void main(String[] args) {
                Resource r=new Resource("鸡腿");
                Input in=new Input(r);
                Output out=new Output(r);
                Thread t1=new Thread(in);
                Thread t2=new Thread(in);
                Thread t3=new Thread(out);
                Thread t4=new Thread(out);
                t1.start();
                t2.start();
                t3.start();
                t4.start();
               
        }

}
class Input implements Runnable
{
        private Resource r;
        Input(Resource r)
        {
                this.r=r;
        }
        public void run()
        {
               while(true)
               {
                  try {
                                        r.set("鸡腿");
                                } catch (InterruptedException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                }
               }
        }
}
class Output implements Runnable
{
        private Resource r;
        Output(Resource r)
        {
                this.r=r;
        }
        public void run()
        {
                while(true)
                {
                        r.get();
               }
        }
}
class Resource
{
        private String name;
        private int count=1;
        private Lock lock=new ReentrantLock();
        private Condition d1=lock.newCondition();
        private Condition d2=lock.newCondition();
        private boolean flag=false;
        public void set(String name) throws InterruptedException
        {
                lock.lock();
          try
          {
                   while(flag)
                            try {
                                                        d1.await();
                                                } catch (InterruptedException e) {
                                                        // TODO Auto-generated catch block
                                                        e.printStackTrace();
                                                }
                   Thread.sleep(1000);
                   this.name=name+"-----"+count++;
                   System.out.println(Thread.currentThread().getName()+"商品***"+this.name);
                   flag=true;//主要是这写反了
                   d2.signal();
                  
            
          }
          finally
          {
                  lock.unlock();
          }
        }
        public void get()
        {
                lock.lock();
                   try
                  {
                            while(!flag)
                                    try{d2.await();}catch(InterruptedException e){}
                           
                                    System.out.println(Thread.currentThread().getName()+"消费***"+name);
                                    flag=false; //主要是这写反了,改过来就好了
                                   d1.signal();
                           
                    
                  }finally
                  {lock.unlock();}
        }
        
        public Resource(String name)
        {
                this.name=name;
        }
        public String getName() {
                return name;
        }
        public void setName(String name) {
                this.name = name;
        }

}
作者: 李伟    时间: 2012-7-24 01:38
public void get()
        {
                lock.lock();
                   try
                  {
                            while(!flag)
                                    try{d2.await();}catch(InterruptedException e){}//这也反了,改过来就行了                           
                                    System.out.println(Thread.currentThread().getName()+"消费***"+name);
                                    flag=false; //主要是这写反了,改过来就好了
                                   d1.signal();
                           
                    
                  }finally
                  {lock.unlock();}
        }

作者: 金龙    时间: 2012-7-24 02:38
问题是出在Resource类中,下面是你Resource类的源代码,后面给注释了,正确代码会在下楼贴上

class Resource
{
        private String name;
        private Lock lock=new ReentrantLock();
        private Condition d1=lock.newCondition();
        private Condition d2=lock.newCondition();
        private boolean flag=false;
        public void set()
        {
                lock.lock();
          try
          {
                    while(flag)
                    {try{d1.await();}catch(InterruptedException e){}}
                    System.out.println(Thread.currentThread().getName()+"商品***"+name);
                    flag=false; //首先,你这里标记错了,原本就是false进来的
                    d2.signalAll();                //所以,那里改成true,还有 唤醒的这个,改成singnl,不用唤醒全部。
            
          }finally
          {lock.unlock();}
        }
        public void get()
        {
                lock.lock();
                   try
                  {
                            while(!flag) //因为你上边的标记改错了,所以这里永远为真
                            {try{d1.await();}catch(InterruptedException e){}}//这里你用的是d1锁,上面唤醒的是d2的哦!所以,永远等待
                            System.out.println(Thread.currentThread().getName()+"消费***"+name);
                            flag=true;//这个标记,从上看,也是反的,应该改为false,消费了没有了就应该是false嘛
                            d1.signalAll();//这里,也不需要唤醒全部的昂。signal就可以了
                    
                  }finally
                  {lock.unlock();}
        }
        
        public Resource(String name)
        {
                this.name=name;
        }
        public String getName() {
                return name;
        }
        public void setName(String name) {
                this.name = name;
        }

}
作者: 金龙    时间: 2012-7-24 02:42
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ThreadDemo3 {
        public static void main(String[] args) {
                Resource r=new Resource("鸡腿");
                Input in=new Input(r);
                Output out=new Output(r);
                Thread t1=new Thread(in);
                Thread t2=new Thread(in);
                Thread t3=new Thread(out);
                Thread t4=new Thread(out);
                t1.start();
                t2.start();
                t3.start();
                t4.start();
               
        }

}
class Input implements Runnable
{
        private Resource r;
        Input(Resource r)
        {
                this.r=r;
        }
        public void run()
        {
                while(true)
                {
                        r.set();
                }
        }
}
class Output implements Runnable
{
        private Resource r;
        Output(Resource r)
        {
                this.r=r;
        }
        public void run()
        {
                while(true)
                {
                        r.get();
                }
        }
}
class Resource
{
        private String name;
        private Lock lock=new ReentrantLock();
        private Condition d1=lock.newCondition();
        private Condition d2=lock.newCondition();
        private boolean flag=false;
        public void set()
        {
                lock.lock();
          try
          {
                    while(flag)
                    {try{d1.await();}catch(InterruptedException e){}}
                    System.out.println(Thread.currentThread().getName()+"商品***"+name);
                    flag=true;//这里是改动后的
                    d2.signal();//这里也是改动后的
            
          }finally
          {lock.unlock();}
        }
        public void get()
        {
                lock.lock();
                   try
                  {
                            while(!flag)
                            {try{d2.await();}catch(InterruptedException e){}}//这里的d2是改动后的
                            System.out.println(Thread.currentThread().getName()+"消费***"+name);
                            flag=false;//这里也是改动后的
                            d1.signal();//同上
                    
                  }finally
                  {lock.unlock();}
        }
        
        public Resource(String name)
        {
                this.name=name;
        }
        public String getName() {
                return name;
        }
        public void setName(String name) {
                this.name = name;
        }

}





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2