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

synchronized 问题
各位老师:
以下程序请帮忙看下,观察运行结果始终不能锁定对象,找不出原因,谢谢了。


public class TestSynchronize extends Thread {
Timer timer = new Timer();
public TestSynchronize(String name) {
super(name);
}
public static void main(String[] arg) {
TestSynchronize t1 = new TestSynchronize("t1");
TestSynchronize t2 = new TestSynchronize("t2");
t1.start();
t2.start();
}

public void run() {
timer.add(Thread.currentThread().getName());
}
}

class Timer {
public static int num = 0;
public synchronized void add(String name) {
//synchronized(this) {
num++;
try {
Thread.sleep(100);
} catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println(name+" num: "+num);
//}
}
}

运行结果:
t1 num: 2
t2 num: 2

------解决方案--------------------
timer对象不是一个,而是两个。
------解决方案--------------------
搂主可以在System.out.println(name+" num: "+num);后面加一语句:
System.out.println(this);就看得清楚了,因为timer对象不是一个,所以没法实现互斥。
楼主可以把timer 对象定成静态的,就能实现同步了。
static Timer timer = new Timer();
------解决方案--------------------
Java code

package cai.thread;

public class TestSynchronize extends Thread {
    public static Timer timer = new Timer();

    public TestSynchronize(String name) {
        super(name);
    }

    public static void main(String[] arg) {
        TestSynchronize t1 = new TestSynchronize("t1");
        TestSynchronize t2 = new TestSynchronize("t2");
        t1.start();
        t2.start();
    }

    public void run() {
        for (int i = 0; i < 5; i++)
            timer.add(Thread.currentThread().getName());
    }
}

class Timer {
    public static int num = 0;

    public synchronized void add(String name) {
        // synchronized(this) {
        num++;
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(name + " num: " + num);
        // }
    }
}

------解决方案--------------------
锁是对象的内存地址

TestSynchronize t1 = new TestSynchronize("t1");
TestSynchronize t2 = new TestSynchronize("t2");
创建了两个Timer对象
导致add方法的锁在两个对象上
Timer timer = new Timer();改为静态的就可以了