请大神们帮帮小弟这个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的方法一样了吗synchronized javathreadRunnble
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的方法一样了吗synchronized javathreadRunnble
解决方案 »
- Mybatis调用oracle存储过程错误问题
- 求一个基于struts 2大文件上传组件【满意高分】
- 求 Struts 增删改查 编程思想
- mysql连接池
- 用javamail发邮件,谁知道如何指定发件人的邮箱地址呢?
- JDBC ORACLE 连接字符串
- 请问如何把servlet里面接收到的参数传到 bean里面去?
- liferay portal的路径中为什么带个/c,啥功能,怎么实现的?(up也有5分呦!)先谢了!
- 请各位解答一下,有关cmp的问题!
- 关于j2ee开发包里是否包含了 j2 s(servlet)dk呢
- 高手帮下忙。JPA实体关系映射中,一对多关系映射怎么设定?
- 项目拷到另一台电脑,结果就报错了,求牛人帮下忙
你想一个线程运行
this.fix(30);
执行完这句话就已经结束了,那么就释放资源,另外一个线程也可以获取,有什么错么?、
如果你想要看效果的话sleep时间应该加在方法内部。
其实楼主的锁是起作用的,两个线程也是交替执行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());
}
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.....