日期:2014-05-20  浏览次数:20753 次

java synchronized问题 求帮忙解释一下
public class Test extends Thread {
Aa a = new Aa();
public void run(){
a.visit();
}
public static void main(String[] args) {

Thread thread1 = new Test();
Thread thread2 = new Test();
thread1.start();
thread2.start();
}
}

class Aa {
private static int i = 0;

public synchronized void visit() {
i++;
try{
Thread.sleep(1);
}catch(InterruptedException e){ }
System.out.println(i);
}


}

输出结果是


而我练习写这段代码想要是结果是 第一行是1 第二行是2
自己把代码修改了好一阵也没有输出 我想要的结果 只好来求助大家。
------解决方案--------------------
public class Test extends Thread {
Aa a;
public Test(Aa a){
this.a = a;
}
public void run(){
a.visit();
}
public static void main(String[] args) {
Aa a = new Aa();
Thread thread1 = new Test(a);
Thread thread2 = new Test(a);
thread1.start();
thread2.start();
}
}

class Aa {
private static int i = 0;

public synchronized void visit() {
i++;
try{
Thread.sleep(1);
}catch(InterruptedException e){ }
System.out.println(i);
}


}

------解决方案--------------------
让thread1.start()后睡一会儿再启动thread2。
不过这样不科学。
科学的还是1楼的做法。
------解决方案--------------------
按照你的写法,每new一个Test对象的时候,就会产生一个新的Aa对象,synchronized方法需要获取对象锁,对象都不一样,所以对象锁也是不一样的。因此你的锁不生效。
------解决方案--------------------
lz你好,猜你是初学Java吧,而且多线程是Java中的一个高级特性,也比较难,从你的分享中看出你喜欢思考哦,上面的代码有一点点需要更改的地方,就是你在main方法中创建了两个Aa对象,但是Aa中的visit方法的同步锁是对象本身,这样两个线程其实拿的不是一把锁,所以不能互斥,那么只要将visit中的代码换一把多个Aa对象可以共享的锁就可以了,希望lz自己先去修改,然后参考下面代码:
public void visit() {
synchronized (Aa.class) {
i++;
try {
Thread.sleep(1);
} catch (InterruptedException e) {
}
System.out.println(i);
}
}

祝lz学习进步,加油,更多关于多线程的学习交流欢迎访问:
http://blog.csdn.net/ysjian_pingcx/article/category/1861379
------解决方案--------------------
因为你的synchronized锁的是当前对象的方法,new了两个Aa,各锁各的,不会达到你预期的竞争操作。
简单的方法,就是在visit方法前再加上static,这样就算是两个Aa,也要竞争同一个静态方法操作权。

或者是将i改成Integer,对i加锁操作:

class Aa {
    private static Integer i = 0;

    public void visit() {
        synchronized (i) {
            i++;
            System.out.println(i);
        }
    }
}

------解决方案--------------------
package demo;

public class Test implements Runnable {
Aa a = new Aa();

public void run() {
a.visit();
}

public static void main(String[] args) {

// 使用同一个runnable对象,这样a对象也是同一个,这时候synchronized才生效
// 方法上的锁是锁的this!!锁的是当前对象!你把你家门锁了,别人进了你隔壁的人家里!你管的着么你! 
Test test = new Test();

// 这时候创建了两个不同的a对象!不同的a对象!相当于两个家!分别有两把长的一样的锁!你进了一个家,锁上门,别人照样能进隔壁家的!
// Thread thread1 = new Test();
// Thread thread2 = new Test();

Thread thread1 = new Thread(test);
Thread thread2 = new Thread(test);
thread1.start();
thread2.start();
}
}

class Aa {
private static int i = 0;

public synchronized void visit() {
i++;
try {
Thread.sleep(1);
} catch (InterruptedException e) {
}
System.out.println(i);
}

}

没有完全理解锁的概念。

可以去看看<<java并发编程实战>>