Java的同步与锁的问题

领带有点歪 2013-01-08 05:59:29
请大神们帮帮小弟这个synchronized问题吧~都纠结好久了,下面这是一个运算类的代码:

public class Foo {

private int x = 100;

public int getX() {
return x;
}

public int fix(int y) {

synchronized (this) {
x = x - y;
}
return x;

}

这下边是主函数的:

public class MyRunable implements Runnable {

/**
* @param args
*/
private Foo foo = new Foo();

public static void main(String[] args) throws InterruptedException {

MyRunable r = new MyRunable();
new Thread(r, "Thread-A").start();
new Thread(r, "Thread-B").start();
}

@Override
public void run() {
for (int i = 0; i < 3; i++) {

this.fix(30);

try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()
+ " 当前foo对象的值为:" + foo.getX());
}

}

public int fix(int y) {
return foo.fix(y);
}


我的输出是这样的:
Thread-A 当前foo对象的值为:40
Thread-B 当前foo对象的值为:40
Thread-A 当前foo对象的值为:-20
Thread-B 当前foo对象的值为:-20
Thread-A 当前foo对象的值为:-80
Thread-B 当前foo对象的值为:-80



可是我锁了运算的方法了阿~为啥还是两个线程同时运行了该方法呢~?要是改怎么改正呢~我如果把synchronized加在run上~那个到时算数对了~可是不就跟jion的方法一样了吗
...全文
129 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
安特矮油 2013-01-08
  • 打赏
  • 举报
回复
代码是没问题的,你把打印放到减法里面

public int fix(int y) {
 
        synchronized (this) {
            x = x - y;
            System.out.println(Thread.currentThread().getName() + "  当前foo对象的值为:" + getX());
        }
        return x;
 
    }
原因在于你的sleep(1000),当A去-30,然后睡1秒,在这一秒当中B-30,A醒了发现变成40了,然后A又-30,但是他还没执行完的时候,B醒了发现也是40.....
zxhcloth 2013-01-08
  • 打赏
  • 举报
回复
呵呵,楼主只看到结果,而忽略了过程了。 其实楼主的锁是起作用的,两个线程也是交替执行foo.fix()方法,但你并不是foo.fix()执行完后马上调用foo.getX(),等你调用foo.getX()时,两个线程的单回合都已经结束了,这一瞬间x的值是一样的。你有没有发现你没有打印70,因为两个线程各减30,所以你打印的是40 你要真想看到效果,请把 System.out.println(Thread.currentThread().getName() + " 当前foo对象的值为:" + foo.getX()); 挪到 synchronized (this) { x = x - y; System.out.println(Thread.currentThread().getName() + " 当前foo对象的值为:" + getX()); }
失落夏天 2013-01-08
  • 打赏
  • 举报
回复
同时运行该方法没有什么不对啊。 你想一个线程运行 this.fix(30); 执行完这句话就已经结束了,那么就释放资源,另外一个线程也可以获取,有什么错么?、 如果你想要看效果的话sleep时间应该加在方法内部。

67,514

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧