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

java多线程synchronized,求解
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,所以说下面的相同数值肯定也会出现的