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句代码,这样没一句代码都有可能被其它线程打断,所以不是线程安全的

    评论

报告相同问题?

悬赏问题

  • ¥15 如何用Labview在myRIO上做LCD显示?(语言-开发语言)
  • ¥15 Vue3地图和异步函数使用
  • ¥15 C++ yoloV5改写遇到的问题
  • ¥20 win11修改中文用户名路径
  • ¥15 win2012磁盘空间不足,c盘正常,d盘无法写入
  • ¥15 用土力学知识进行土坡稳定性分析与挡土墙设计
  • ¥70 PlayWright在Java上连接CDP关联本地Chrome启动失败,貌似是Windows端口转发问题
  • ¥15 帮我写一个c++工程
  • ¥30 Eclipse官网打不开,官网首页进不去,显示无法访问此页面,求解决方法
  • ¥15 关于smbclient 库的使用