wujiqiankun 2015-06-29 08:34 采纳率: 0%
浏览 1500

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

先上代码:

 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 移动开发领域优质创作者 2015-06-29 08:43
    关注

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

    评论

报告相同问题?

悬赏问题

  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 spring后端vue前端
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名
  • ¥65 汇编语言除法溢出问题
  • ¥15 Visual Studio问题