2 zfy1355 zfy1355 于 2016.03.04 18:33 提问

关于ReentrantLock使用的疑问?

直接上代码:

import java.util.concurrent.locks.ReentrantLock;

public class MulThreadTest {
        public static int a = 0;

        ReentrantLock lock = new ReentrantLock(true);
        public void addInt(){
            lock.lock();
            a++;
            System.out.println(Thread.currentThread().getName()+"___________"+a +"_     " + lock.getHoldCount());
            lock.unlock();
        }
    public static void main(String[] args) throws InterruptedException {
            for(int i=0;i<3;i++){
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        MulThreadTest test = new MulThreadTest();
                        for(int j=0;j<100;j++)
                            test.addInt();
                    }
                },"thread"+i).start();
            }
        }
     }

运行结果总会丢数字,难道是使用方法有问题?帮忙解答一下~

2个回答

u013596119
u013596119   Rxr 2016.03.04 22:20
已采纳

你在每个线程里都建立了不同的text,也就是有三个不同的a在三个不同的test的实例里,这样改就可以了,三个线程访问的是同一个test实例,addInt也是针对同一个a,这样输出就可以看出lock的作用了


import java.util.concurrent.locks.ReentrantLock;

public class MulThreadTest {
        public static int a = 0;

        ReentrantLock lock = new ReentrantLock(true);
        public void addInt(){
            lock.lock();
            a++;
            System.out.println(Thread.currentThread().getName()+"___________"+a +"_     " + lock.getHoldCount());
            lock.unlock();
        }
    public static void main(String[] args) throws InterruptedException {
            final MulThreadTest test = new MulThreadTest();
            for(int i=0;i<3;i++){
                new Thread(new Runnable() {
                    @Override
                    public void run() {

                        for(int j=0;j<100;j++)
                            test.addInt();
                    }
                },"thread"+i).start();
            }
        }
     }
u013596119
u013596119 每个线程访问自己的对象就不存在synchronized的问题了
2 年多之前 回复
u013596119
u013596119 你new出来的是整个MulThreadTest,每个对象都有自己的a,a只是每个MulThreadTest实例的一个变量,我的代码里是只有一个对象,三个线程同时访问这一个对象的a,你的代码里是多个test,每个线程访问自己的test对象
2 年多之前 回复
zfy1355
zfy1355 a是静态变量,new出的每一个对象都是共享a对象的,所以不存在多个a对象的
2 年多之前 回复
wojiushiwo945you
wojiushiwo945you   Ds   Rxr 2016.03.05 13:25

锁同步是针对共享数据的,多线程对共享变量访问时,会涉及到数据竞争问题。
你的代码的问题是每个线程中都新new了一个MulThreadTest对象,单线程中访问各自的数据,就不存在互斥访问的问题了。
就好比每个人家都有WC,每个人访问的是自己家的WC,那么就不可能存在竞争等待问题。但是如果是公共区域,共享的WC,那么就需要锁同步了。

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐
ReentrantLock中lock/trylock/lockInterruptibly方法的区别及源码解析
看了几篇关于这三者区别的文章,但都说的不够具体,自己去读了下源码,大概是清楚了三者的功能。 首先,ReentrantLock类中使用了大量的CAS操作,也就是CompareAndSwap原子操作,依靠硬件保证互斥与同步,然后说下interrupt()方法。每个线程都有一个interrupt标志。当线程在阻塞状态时,如sleep、wait、await(park)、join,此时如果对该进程调用in
Thread详解13:ReentrantLock的用法(一)
Java里面提供了比synchronized更加灵活丰富的锁机制,它们有一个共同的接口Lock,我们先来学习这个接口,了解其协议和功能。下面是JDK文档,总结得非常精炼,包含的知识点非常多,所以一开始可能看不懂,不过没关系,后面一点点弄懂。public interface LockLock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作。此实现允许更灵活的结构,可以具
ReentrantLock使用场景以及注意事项
package userWeb; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; public class ReentrantLockTest { public static ReentrantLock reenT=new ReentrantLock
Java多线程之~~~Lock接口和ReentrantLock的使用
在多线程开发中,除了synchronized这个关键字外,我们还能通过Lock接口来实现这种效果。通过Lock接口来实现 这种多线程加锁效果的好处是非常的灵活,我们不在需要对整个函数加锁,而且可以很方便的把他放在我们函数的任何 一个地方,非常的称心,而且从效率上来说,使用Lock接口要比使用synchronized关键字效率高一些,下面我们来使用 一个例子来说明这种方法的使用。 p
ReentrantLock使用场景和实例
转载来源:https://my.oschina.net/noahxiao/blog/101558从使用场景的角度出发来介绍对ReentrantLock的使用,相对来说容易理解一些。可重入概念 若一个程序或子程序可以“安全的被并行执行(Parallel computing)”,则称其为可重入(reentrant或re-entrant)的。即当该子程序正在运行时,可以再次进入并执行它(并行执行时,个别
并发编程学习总结(五) :java 显式锁ReentrantLock使用详解之条件对象(2)
(1) ReentrantLock的条件对象 通常,线程进入临界区,却发现在某一条件满足之后才能执行,条件对象就是用来管理那些已经获得了锁,但是却不能做有用工作的线程。 一个锁对象可以有一个或多个相关的条件对象,我们可用lock.newCondition()方法获得一个条件对象。 ReentrantLock myLock = new ReentrantLock(); // 获得锁myLock
ReentrantLock 和 Condition的使用
ReentrantLock ReentrantLock可以等同于synchronized使用。 ReentrantLock 类实现了Lock ,它拥有与 synchronized 相同的并发性和内存语义,但是添加了类似锁投票、定时锁等候和可中断锁等候的一些特性。此外,它还提供了在激烈争用情况下更佳的性能。(换句话说,当许多线程都想访问共享资源时,JVM 可以花更少的时候来调度线程,把更
Netty------对于Netty的十一个疑问
1.Netty 是什么?   Netty 是一个基于 JAVA NIO 类库的异步通信框架,它的架构特点是:异步非阻塞、基于事件驱动、高性能、高可靠性和高可定制性。   2.使用 Netty 能够做什么? 开发异步、非阻塞的 TCP 网络应用程序; 开发异步、非阻塞的 UDP 网络应用程序; 开发异步文件传输应用程序; 开发异步 HTTP 服
Whatspay将有望充当未来数字货币交易“媒介”桥梁
货币发展大致遵循由自然货币向人工货币的演变,由杂乱形状向规范形状的演变,由地方铸币向中央铸币的演变,由金属货币向纸币交子的演变,由手工印币向机制印币的演变。这是一个由复杂向简单,由杂乱向规则,由繁冗向快捷,由沉重向轻便的发展过程。近几十年来,世界经济进一步呈现全球化趋势,各经济体之间的经济联系更加紧密,全球金融市场跨越了地域的限制,产品种类、交易频率、规模是以前所无法比拟的。纸币已经无法满足这样的...
ReentrantLock(二):正确使用Condition实现等待与通知
关键字synchronized与wait()和notify()/notifyAll()方法相结合可以实现等待/通知模式。 类ReentrantLock同样可以实现该功能,但是要借助于Condition对象。它具有更好的灵活性,比如可以实现多路通知功能,也就是在一个Lock对象里面可以创建多个Condition(对象监视器)实例,线程对象可以注册在指定Condition中,从而有选择性的进行线程通知