java多线程synchronized,求解

goldmei88 2014-01-08 11:56:48
public class MyRunnable implements Runnable {
private int x = 100;

@Override
public void run() {
for (int i = 0; i < 3; i++) {
synchronized (this) {
this.fix(30);

try {
Thread.sleep(1);
} catch (final InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + ":当前对象foo的x值=" + x);
}
}

public static void main(final String[] args) {
final MyRunnable r = new MyRunnable();
final Thread ta = new Thread(r, "Thread-A");
final Thread tb = new Thread(r, "Thread-B");
ta.start();
tb.start();
}

public int fix(final int y) {
x = x - y;
return x;
}

}

为什么锁定
synchronized (this) {
this.fix(30);

try {
Thread.sleep(1);
} catch (final InterruptedException e) {
e.printStackTrace();
}
}

会出现这样的结果(有相同的值出现):

Thread-A:当前对象foo的x值=40
Thread-B:当前对象foo的x值=40
Thread-B:当前对象foo的x值=10
Thread-B:当前对象foo的x值=-50
Thread-A:当前对象foo的x值=-50
Thread-A:当前对象foo的x值=-80
...全文
223 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
goldmei88 2014-01-09
  • 打赏
  • 举报
回复
明白了,谢谢各位的解答。
kevinlifeng 2014-01-09
  • 打赏
  • 举报
回复
引用 9 楼 Lsheep 的回复:
[quote=引用 1 楼 anshiny 的回复:]

public void run() {
	for (int i = 0; i < 3; i++) {
		synchronized (this) {
			this.fix(30);
			try {
				Thread.sleep(1);
			} catch (final InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()
				+ ":当前对象foo的x值=" + x);
		}
	}
}
这位同学已经给出答案了,请把输出语句也锁住呀,不然输出语句执行之前被打断,再受到调度后打印出来的已经不是原来的值了。[/quote]顶一个,当什么时候synchronized的块结束,这个锁就释放了,所以把system.out.println("xxxx")放入synchronized的块中,给执行完了,才释放锁
anshiny 2014-01-08
  • 打赏
  • 举报
回复

public void run() {
	for (int i = 0; i < 3; i++) {
		synchronized (this) {
			this.fix(30);
			try {
				Thread.sleep(1);
			} catch (final InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()
				+ ":当前对象foo的x值=" + x);
		}
	}
}
Lsheep 2014-01-08
  • 打赏
  • 举报
回复
引用 1 楼 anshiny 的回复:

public void run() {
	for (int i = 0; i < 3; i++) {
		synchronized (this) {
			this.fix(30);
			try {
				Thread.sleep(1);
			} catch (final InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()
				+ ":当前对象foo的x值=" + x);
		}
	}
}
这位同学已经给出答案了,请把输出语句也锁住呀,不然输出语句执行之前被打断,再受到调度后打印出来的已经不是原来的值了。
java--小强 2014-01-08
  • 打赏
  • 举报
回复
我就说你的第一个和第二个的情况吧,当第一个进程进来后,执行函数操作后,为70,正准备要打印,这是Cpu把线程切换到了第二个上,第二个线程进来,继续进行函数操作后,运算后为40,此时有切换到第一个打印出来的肯定是40,在切换到第二个上,打印出来也是40,所以说下面的相同数值肯定也会出现的
java--小强 2014-01-08
  • 打赏
  • 举报
回复
很明显这是没有同步到,不可能有相同的数值,我这边现在不能给你测试,你把打印语句搞去里面试下
Test_LD 2014-01-08
  • 打赏
  • 举报
回复
System.out.println(Thread.currentThread().getName() + ":当前对象foo的x值=" + x); 这个比较耗时,当A执行完synchronized中的代码x=70, 开始要syso时, B线程过来修改了x的值x=40 然后也开始syso,A syso出40,B也syso出40 我想应该是这样- -
骑士的崛起 2014-01-08
  • 打赏
  • 举报
回复
引用 楼主 u011712163 的回复:
会出现这样的结果(有相同的值出现):

Thread-A:当前对象foo的x值=40
Thread-B:当前对象foo的x值=40
Thread-B:当前对象foo的x值=10
Thread-B:当前对象foo的x值=-50
Thread-A:当前对象foo的x值=-50
Thread-A:当前对象foo的x值=-80
不知道这几位朋友在疑问什么? 当Thread-A到16行时,Thread-B同样可以执行到8行。x先被减30还先被打出没准,出现这个结果很正常。
fyb_java 2014-01-08
  • 打赏
  • 举报
回复
synchronized起作用了,你可以这样跟一个下代码就明白了: ta.start();ta先开启线程,然后执行synchronized里面的代码,遇到Thread.sleep(1);ta睡眠了,可是没有释放执行权,tb是不可能执行的,这时ta继续执行,执行完synchronized里面的代码,这时突然tb抢到执行权了,tb执行,这时x=70;tb执行完synchronized里面的代码后,ta抢到执行权,这时x=40;ta执行打印语句,x=40,执行完tb获取执行权又一次打印x=40;这时就会出现打印两次x=40的情况,接着tb继续执行,打印语句会出现x=10的情况,然后ta执行,打印语句前被tb获取执行权,这时x=-50,打印x=-50,这时tb三次执行完了,后面的就好解释了。
goldmei88 2014-01-08
  • 打赏
  • 举报
回复
引用 2 楼 jakie_wang 的回复:
我试过一下,发现将synchronized 放在整个方法前,是没有问题的。 楼主的问题我也挺好奇的,感觉是synchronized 没起作用似的,等高手回答
是啊,最近在看Java多线程,好迷惑啊!
锅盖头 2014-01-08
  • 打赏
  • 举报
回复
我试过一下,发现将synchronized 放在整个方法前,是没有问题的。 楼主的问题我也挺好奇的,感觉是synchronized 没起作用似的,等高手回答

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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