public class J_Test implements Runnable 

int m_x,m_y; 
public void mb_setX(int i) 

m_x=i; 

public void mb_setY(int i) 

m_y=i; 

public synchronized void mb_setXY(int i) 

mb_setX(i); 
mb_setY(i); 

public void run() 

for(int i=0; i>=0;i++) 

mb_setXY(i); 
if(m_x!=m_y) System.out.println(m_x+"!"+m_y); 


public static void main(String args[]) 

J_Test s=new J_Test(); 
Thread t1=new Thread(s); 
Thread t2=new Thread(s); 
t1.start();t2.start(); 


请问各位:这道题的结果为何会输出一些带不等号的结果?synchronized void mb_setXY这个方法不是被加上锁了吗? 
 
 

解决方案 »

  1.   

    synchronized void mb_setXY这个方法是锁上了,可是run()方法并没有锁上,把run()也锁上就不带不等号了 public class J_Test implements Runnable {
    int m_x, m_y; public void mb_setX(int i) {
    m_x = i;
    } public void mb_setY(int i) {
    m_y = i;
    } public synchronized void mb_setXY(int i) {
    mb_setX(i);
    mb_setY(i);
    } public synchronized void  run() {
    for (int i = 0; i >= 0; i++) {
    mb_setXY(i);
    if (m_x != m_y)
    System.out.println(m_x + "!" + m_y);
    }
    } public static void main(String args[]) {
    J_Test s = new J_Test();
    Thread t1 = new Thread(s);
    Thread t2 = new Thread(s);
    t1.start();
    t2.start();
    }
    }
      

  2.   

    加锁先看是不是线程间有无共享的对象
    有则synchronized作用
    否则无
    lz代码看的头晕
    写写人和动物多好呢
      

  3.   

    你好gao11811!谢谢你为我解释了这个关于初学者关于:线程中同步的问题,可我想发很久,不太明白这段话的意思“你给的代码没有使用到synchronized的意义,你把它去掉结果是一样的 
    因为你启用的2个线程,他们自身的xy是独立的,绝对不会被另外一个影响到 
    出现!=的情况原因,是因为一个线程的mb_setXY()在执行的时候被另一个线程抢去了执行权,而导致自身的x,y的一次输出不同,实际还是相同的。 
    这个现象就直接说明,这里的方法mb_setXY在2个线程中都有独立的内存,synchronized不能起到作用 其实,这个代码并没有给线程类传值,而且是用了for循环,for中的i很明显只在for循环中有效,怎么可能被其他的线程影响 ”你给我看的例程我能看明白你的意思,请你能再帮我把这句话讲的浅显些吗?我刚学JAVA,挺笨的,谢谢你啊
      

  4.   

    关于2楼在run方法上加上关键字synchronized的程序我跑了下,发现确实不会打印if语句中的“!=”了。因为run方法只被单一的一个线程给霸占了,另一个线程并没有运行,结果自然没有“!=”。这样以来,多线程似乎没起到其本来的作用了。对一个类中的成员变量和成员方法,如果生成这类的几个对象,每个对象都会有一份类中成员变量的拷贝,但每个对象都会共享同一个成员方法(成员方法在内存只有一份拷贝)。打印不同的结果很显然是因为for循环中的i被两个线程共同使用了。不知道这样解释可否。
    还有个奇怪问题是,我在类中定义for中的那个i为成员变量,然后在for循环中这样用:
    for(; this.i>=0; i++)  通过打印的信息发现,两个线程还是共想享了i,于是范迷糊了。以下是代码:
    public class SynchronizedTest implements Runnable {
        int m_x, m_y;
        private int i;    public void mb_setX(int i) {
            m_x = i;
        }    public void mb_setY(int i) {
            m_y = i;
        }    public synchronized void mb_setXY(int i) {
            mb_setX(i);
            //System.out.println(Thread.currentThread().toString()+"m_x="+m_x);
            mb_setY(i);
           // System.out.println(Thread.currentThread().toString()+"m_y="+m_y);
        }    public  void run() {
         //System.out.println(Thread.currentThread());
            for (; this.i >= 0; this.i++) {
               //System.out.println(Thread.currentThread().toString()+" i = "+i);
                mb_setXY(this.i);
                //System.out.println("middle"+Thread.currentTh read()+m_x+" "+m_y);
                if (m_x != m_y)
                    System.out.println(Thread.currentThread().toString()+m_x + "!" + m_y);
            }
        }    public static void main(String args[]) {
            SynchronizedTest s = new SynchronizedTest();
            Thread t1 = new Thread(s);
            Thread t2 = new Thread(s);
            t1.start();
            t2.start();
        }
    }代码运行的部分结果:
    Thread[Thread-1,5,main]2821!2853
    Thread[Thread-0,5,main]3776!3782
    Thread[Thread-1,5,main]4308!4314
    Thread[Thread-1,5,main]4763!4769
    Thread[Thread-0,5,main]5252!5258
    Thread[Thread-0,5,main]5671!5677
    Thread[Thread-0,5,main]6142!6148
    Thread[Thread-0,5,main]6590!6596
    Thread[Thread-1,5,main]6996!7002
    Thread[Thread-1,5,main]7415!7421
    Thread[Thread-1,5,main]7827!7833
    Thread[Thread-0,5,main]8217!8223
    Thread[Thread-0,5,main]8629!8635
    Thread[Thread-1,5,main]9174!9179
    Thread[Thread-0,5,main]9588!9593
    Thread[Thread-1,5,main]9994!10000
    Thread[Thread-0,5,main]10435!10441
      

  5.   

    不好意思,楼主,我原来的解释不是很正确
    2个线程拥有独立的内存,但是他们共享了同一个资源s,但是不包括for中的i,m_x和m_y是共享的,但是i是独立的,因为i是局部变量,所以2个线程拥有独立的i,这样就产生了!=的问题,详细如下
    经过如下修改代码测试:public synchronized  void mb_setXY(int i) 
    {mb_setX(i); 
    System.out.println(Thread.currentThread().getName()+":2");
    mb_setY(i); 
    System.out.println(Thread.currentThread().getName()+":3");


    public  void run() 

    for(int i=0; i<=1000;i++) 

    mb_setXY(i); 
    System.out.println(Thread.currentThread().getName()+":"+m_x+":"+m_y);if(m_x!=m_y) System.out.println(Thread.currentThread().getName()+":"+m_x+"!"+m_y); 

    } 部分结果:
    Thread-0:2
    Thread-1:348:348
    Thread-0:3
    Thread-0:458:458
    Thread-0:349!458
    Thread-1:2
    Thread-1:3
    出现!=的原因是:
    1 可以看到,当Thread-0:2出现后,执行权被Thread-1拿去
    2 此时,1线程的xy都是348,也就是Thread-1的i是348,if语句应该也被执行,因为相同,所以没有输出
    3 然后,Thread-0马上夺回执行权,打印Thread-0:3,继续执行打印Thread-0:458:458,说明Thread-0的i是458
    4 但是这个时候,Thread-1再次夺取执行权,执行了新的循环的i++,此时Thread-1的i是349,然后继续执行mb_setXY(i)中的mb_setX(i),将x置为349
    5 突然,Thread-0又夺回线程,继续执行if(m_x!=m_y),因为此时的x是349,y是原来的458,所以出现Thread-0:349!458
    6 最后Thread-1夺回线程执行mb_setXY(i)余下的代码,打印Thread-1:2,Thread-1:3
    以上就是2个线程交叉执行一次for的过程,也正是导致!=的原因可见,因为没有准确安排synchronized的对象,导致了程序的交叉
    如1楼,可以将run锁住,虽然那样有点浪费,最好的方式,应该是通过成员变量来控制for循环,然后锁成员变量就可以了
      

  6.   

    嗯,我上面改成成员变量确实不够彻底。
    这下清楚了,将那个for语句放在了synchronized(Object o){}里面就好了。
    不过,两个对象t1和t2为什么会出现“m_x和m_y是共享的”。不是每个类对象都保有一份对成员变量的拷贝吗?
      

  7.   

    又错了,哎!不好意思,抱歉 gao11811.
    明白了,是我看错了,以为生成了两个s了。杯具了。