黑马程序员技术交流社区

标题: 线程问题,有不符合实际的数据 [打印本页]

作者: 杨习平    时间: 2012-9-10 02:27
标题: 线程问题,有不符合实际的数据
public class ThreadTest1 {
                  private int j;
                  public static void main(String args[]){
                ThreadTest1 tt=new ThreadTest1();
                Inc inc=tt.new Inc();
                Dec dec=tt.new Dec();
                for(int i=0;i<2;i++){
                Thread t=new Thread(inc);
                t.start();
                t=new Thread(dec);
                t.start();
                }
                }
                  private synchronized void inc(){
                j++;
                System.out.println(Thread.currentThread().getName()+"-inc:"+j);
                  }
                  private synchronized void dec(){
                j--;
                System.out.println(Thread.currentThread().getName()+"-dec:"+j);
                  }
                  class Inc implements Runnable{
                public void run(){
                for(int i=0;i<100;i++){
                inc();
                }
                }
                  }
                  class Dec implements Runnable{
                public void run(){
                for(int i=0;i<100;i++){
                dec();
                }
                 }
                }
        }
帮帮找找错误的原因,求助,高手。。??执行结果为什么是不符合现实。
作者: 黑马_许芸    时间: 2012-9-10 08:03
额,不太懂你说的“不符合现实”是啥意思?在我看来,你启动了四个线程,对这个具有同步锁的资源j操作了400次,增和减各200次,最终的结果还是0.大哥,你要滴现实是啥子嘛?
作者: 班志国    时间: 2012-9-10 08:30
代码写的太乱不好阅读
作者: 杨习平    时间: 2012-9-10 13:34
对不起,我没说清楚,我是说线程启动后执行的结果是错误的,还有负数的票。是不是不符合实际啊,你们怎么想的,我想在知道了点原因,但还是请求你们高手详解。
作者: 杨震    时间: 2012-9-10 14:03
你这就是启动四个线程,两个对j进行加,两个对j进行减,如果减的线程执行的多,当然是出现负值啊.

不知道你想实现什么功能?模拟售票?inc表示产生票?dec表示售出票?如果这样的话你的dec要判断下啊,如果j > 0才能售票才能减,否则没有票怎么卖啊
作者: 黑马_许芸    时间: 2012-9-10 14:26
本帖最后由 黑马_许芸 于 2012-9-10 14:31 编辑

//因为线程启动之后就木有啥先后顺序了,谁抢到资源就执行谁呗。所以你的程序出现负值很正常么,说明截止到那个时间点 j-- 的次数比 j++ 的次数多点而已嘛。如果你不想让执行结果中出现负值,可以使用 wati() 和 notify() 来进行控制,只需要分别在你的inc() 和 dec() 中加句话就行了。如下所示:

private synchronized void inc()
{
  j++;
  System.out.println(Thread.currentThread().getName() + "-inc:" + j);
  if (j>=1)
  {
   notify();  //如果 j>=1 了,就可以通知其他在等待的线程了,唤醒一个线程,但并不是马上就开始执行那个线程,还有等到当前线程释放资源。
  }
}
private synchronized void dec()
{
  if (j <= 0)
  {
   try
   {
    wait();  //如果 j<=0 了,就不能再减了,免得出现负值嘛。释放资源等待吧。
   } catch (InterruptedException e)
   {
    e.printStackTrace();
   }
  }
  j--;
  System.out.println(Thread.currentThread().getName() + "-dec:" + j);
}

作者: 陈俊来    时间: 2012-9-10 15:24
lz你的程序很正常,.
作者: 杨习平    时间: 2012-9-10 15:29
还是地板给力啊。谢谢,就是这样的效果,问题总算解决。




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