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这个方法不是被加上锁了吗?
{
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这个方法不是被加上锁了吗?
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();
}
}
有则synchronized作用
否则无
lz代码看的头晕
写写人和动物多好呢
因为你启用的2个线程,他们自身的xy是独立的,绝对不会被另外一个影响到
出现!=的情况原因,是因为一个线程的mb_setXY()在执行的时候被另一个线程抢去了执行权,而导致自身的x,y的一次输出不同,实际还是相同的。
这个现象就直接说明,这里的方法mb_setXY在2个线程中都有独立的内存,synchronized不能起到作用 其实,这个代码并没有给线程类传值,而且是用了for循环,for中的i很明显只在for循环中有效,怎么可能被其他的线程影响 ”你给我看的例程我能看明白你的意思,请你能再帮我把这句话讲的浅显些吗?我刚学JAVA,挺笨的,谢谢你啊
还有个奇怪问题是,我在类中定义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
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循环,然后锁成员变量就可以了
这下清楚了,将那个for语句放在了synchronized(Object o){}里面就好了。
不过,两个对象t1和t2为什么会出现“m_x和m_y是共享的”。不是每个类对象都保有一份对成员变量的拷贝吗?
明白了,是我看错了,以为生成了两个s了。杯具了。