java多线程synchronized,求解,该如何解决
java多线程synchronized,求解
为什么锁定
会出现这样的结果(有相同的值出现):
------解决方案--------------------
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三次执行完了,后面的就好解释了。
------解决方案--------------------
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
我想应该是这样- -
------解决方案--------------------
我就说你的第一个和第二个的情况吧,当第一个进程进来后,执行函数操作后,为70,正准备要打印,这是Cpu把线程切换到了第二个上,第二个线程进来,继续进行函数操作后,运算后为40,此时有切换到第一个打印出来的肯定是40,在切换到第二个上,打印出来也是40,所以说下面的相同数值肯定也会出现的
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
------解决方案--------------------
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三次执行完了,后面的就好解释了。
------解决方案--------------------
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
我想应该是这样- -
------解决方案--------------------
我就说你的第一个和第二个的情况吧,当第一个进程进来后,执行函数操作后,为70,正准备要打印,这是Cpu把线程切换到了第二个上,第二个线程进来,继续进行函数操作后,运算后为40,此时有切换到第一个打印出来的肯定是40,在切换到第二个上,打印出来也是40,所以说下面的相同数值肯定也会出现的