2 wujiqiankun wujiqiankun 于 2015.06.29 16:34 提问

请教一个很奇葩的线程加锁问题

先上代码:

 import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class MySyncObject {
    private Integer count = 0;
    private Integer obj = 0;

    private Lock lock = new ReentrantLock();

    public void increment() {
        synchronized (count) {
            //      lock.lock();
            //      try {
            for (int i = 0; i < 10; i++) {
                System.out.println("++");
                count++;
                Thread.yield();
            }
            //      } finally {
            //          lock.unlock();
        }
        //      }
    }

    public void decrement() {
        synchronized (count) {
            //      lock.lock();
            //      try {
            for (int i = 0; i < 10; i++) {
                System.out.println("--");
                count--;
                Thread.yield();
            }
            //      } finally {
            //          lock.unlock();
        }
    }

    public int get() {
        return count;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        final MySyncObject obj = new MySyncObject();

        new Thread(new Runnable() {
            @Override
            public void run() {
                obj.increment();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                obj.decrement();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    System.out.println("check:" + obj.get());
                    Thread.yield();
                }
            }
        }).start();
    }
}

我在对象count上加锁,试图控制线程的同步。但是运行结果,却出乎我的意料。如下:

 ++
--
check:0
++
--
check:0
++
--
check:0
++
--
check:0
++
--
check:0
++
--
check:0
++
--
check:0
++
--
check:0
++
--
check:0
++
--
check:0

而使用obj代替count的时候,却可以正常工作。使用lock也正常。结果如下:

 ++
check:1
++
check:2
++
check:3
++
check:4
++
check:5
++
check:6
++
check:7
++
check:8
++
check:9
++
check:10
--
--
--
--
--
--
--
--
--
--

这是为什么呢?难道对count执行++,或--操作会导致锁失效吗?

请看清楚,我使用了 synchronized (count) ,理论上,在执行yeid的时候,另一个线程会阻塞,因为count加锁了。但实际上,测试发现可以运行。
而使用 synchronized (obj)对另一个对象加锁时,另一个线程却会阻塞住。符合之前的预期。

1个回答

bdmh
bdmh   Ds   Rxr 2015.06.29 16:43

对dount进行操作,不是原子的,转成汇编可能要3句代码,这样没一句代码都有可能被其它线程打断,所以不是线程安全的

wujiqiankun
wujiqiankun 为什么我用 synchronized (count) 不行,而使用 synchronized (obj)却可以?????
2 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片