多线程的同步锁问题 多线程Lock 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 lock /unlock里面的内容是什么啊? 锁的含义,相信你是明白的,锁是为了独占某个资源,当 A 资源被占用之后,如果有别的线程希望占用 A 资源,那么就需要等到资源释放.在这里的话, 当你执行 getTotalBlance 就是代表着,当你计算总收支平衡的时候,不允许对账户进行操作,以避免你计算错误,例如甲乙两个账户,你计算了甲账户之后,从甲账户汇了钱到乙账户,如果你不暂停对所有账户的操作,那么你在计算乙账户的时候,重复的计算了刚汇来的那笔钱,得到的结果就是错误的 兄台,你的意思我明白。我分析一下思路吧,当甲调用了transfer方法,获得了锁,他在里面进行了汇款给乙,甲的钱少了,乙的钱多了,然后他想计算总的存款量,他又要调用getTotalBalance()方法,这个方法也是需要锁的,可是甲的锁是在finally里面释放的(见代码),那么甲进入getTotalBalance()方法的时候,他获取的是哪一把锁呢。我这里的锁是基于Bank_Test的某一个实例的,因为甲,乙是操作的同一个实例的内容,所以肯定是用的同一把锁我的主要困惑是,在调用getTotalBalance()方法的时候怎么去理解甲的锁还没有释放,还请兄台明示! 你可以理解为,在 getTotalBalance()中,我们去想系统申请说,诶,系统,我要一个人占用某个资源;如果系统中有人已经占用了,然后系统就说,现在有人在使用,你先等着吧,然后我们就只要在那儿等着系统释放资源,然后拿到了系统的允许之后再向下执行 楼主能解释下具体解释下什么意思吗?当一个线程进入transfer()方法的时候,他获得了锁。获得了哪个对象的锁?这个银行类需要操作具体的客户类?获得的锁是什么锁。 请别截图好么 使用代码格式粘贴,大家都会很好看。复制代码放到那个两个code标签之间,就这么简单。 引用一下楼主的原话我的主要困惑在于,当一个线程进入transfer()方法的时候,他获得了锁,但是他同时调用了getTotalBalance()方法System.out.printf("Total Balance:%10.2f%n",getTotalBalance()); 可是,这个方法也是需要锁的,而且他们用的是同一把锁那么,当我执行上面代码的时候,到底发生了什么呢,还请大侠们明示!你是没理解清楚同步锁的含义。首先,是线程获取锁,而不是transfer()或者是getTotalBalance()方法获取锁。理论上来说,一个线程可以多次对同一个对象上锁。对于每一个对象,java虚拟机维护一个加锁计数器,线程每获得一次该对象,计数器就加1,每释放一次,计数器就减 1,当计数器值为0时,锁就被完全释放了。所以,是这个线程获取了同一个对象的两次锁。你问会发生什么?答案是:在同一个线程中transfer()和getTotalBalance()方法不会起到同步的效果。代码跑到哪里就运行什么,第二次look是没效果的。为什么说是理论上呢?因为我实在想不出你的look/unlook代码是怎么写的我想到的线程同步,首先是synchronized关键字。你这look/unlook用法,怎么看也不像是用synchronized关键字。 小弟初来乍到,如果在格式上有什么不妥,我下次一定改正不过看后@全小范的回答,我又在网上查了一下,我应该是明白了其实大家不用纠结我具体在干什么,如果大家能仔细听我说的话,其实事情是这样的:线程甲乙共同操作一个类的实例对象,线程甲此时进入transfer()方法,拿到了对象的锁,他便开始运行代码,然后,他会调用一个方法getTotalBalance(),问题就出来了,那么这个方法需要同步吗? 如小范所说,可以不用同步,因为这个方法是在甲拿到锁之后,释放锁之前调用的,他是同步的,也就是说线程甲必须执行完这个方法,如果transfer()还需要调用其他方法,那个方法也必须被执行完,依次类推。 接下来的问题,如果getTotalBalance()里面也调用了Lock.lock()呢? 好的,这样也是可以的,因为一个线程可以对同一对象多次上锁,如果getTotalBalance()里面被线程上了锁,他执行完之后这个锁必须被释放,对于每一个对象,虚拟机会有一个加锁计数器,你加一次锁,计数加一,一个对象的锁真正被释放就意味着计数器必须为0(我还不清楚加锁和解锁是不是必须要对应),我的大致想法如下,有什么错误,恳请指出,大家一起学习! 首先比较同意是线程获取了锁,lock是一把锁多个监视器,这个比synchronized强大了很多,但是似乎也麻烦了不少了,synchronized将同步和锁绑定在一起了。 lz这种情况还有没有更高效的处理方法? 关于反射,得不到输入内容,全是初始值 用DOM技术解析xml文件内存溢出问题 log4j 是否可以输出到excel中,有没有什么的appender 我想用java来写一个NetMeeting大家给点建议 Japplet 关闭副窗口,却把主窗口也关闭了??? 偶像们来帮忙 搜索后没能解决的问题 jdk压缩包如何设置 请教有关"taglib"的问题? java android sdk 问题 使用键盘画直线
兄台,你的意思我明白。
我分析一下思路吧,当甲调用了transfer方法,获得了锁,他在里面进行了汇款给乙,甲的钱少了,乙的钱多了,然后他想计算总的存款量,他又要调用getTotalBalance()方法,这个方法也是需要锁的,可是甲的锁是在finally里面释放的(见代码),那么甲进入getTotalBalance()方法的时候,他获取的是哪一把锁呢。
我这里的锁是基于Bank_Test的某一个实例的,因为甲,乙是操作的同一个实例的内容,所以肯定是用的同一把锁
我的主要困惑是,在调用getTotalBalance()方法的时候怎么去理解甲的锁还没有释放,还请兄台明示!
你可以理解为,在 getTotalBalance()中,我们去想系统申请说,诶,系统,我要一个人占用某个资源;如果系统中有人已经占用了,然后系统就说,现在有人在使用,你先等着吧,然后我们就只要在那儿等着系统释放资源,然后拿到了系统的允许之后再向下执行
System.out.printf("Total Balance:%10.2f%n",getTotalBalance());
可是,这个方法也是需要锁的,而且他们用的是同一把锁
那么,当我执行上面代码的时候,到底发生了什么呢,还请大侠们明示!
你是没理解清楚同步锁的含义。首先,是线程获取锁,而不是transfer()或者是getTotalBalance()方法获取锁。
理论上来说,一个线程可以多次对同一个对象上锁。对于每一个对象,java虚拟机维护一个加锁计数器,线程每获得一次该对象,计数器就加1,每释放一次,计数器就减 1,当计数器值为0时,锁就被完全释放了。所以,是这个线程获取了同一个对象的两次锁。你问会发生什么?
答案是:在同一个线程中transfer()和getTotalBalance()方法不会起到同步的效果。代码跑到哪里就运行什么,第二次look是没效果的。为什么说是理论上呢?因为我实在想不出你的look/unlook代码是怎么写的
我想到的线程同步,首先是synchronized关键字。你这look/unlook用法,怎么看也不像是用synchronized关键字。
小弟初来乍到,如果在格式上有什么不妥,我下次一定改正
不过看后@全小范的回答,我又在网上查了一下,我应该是明白了
其实大家不用纠结我具体在干什么,如果大家能仔细听我说的话,其实事情是这样的:
线程甲乙共同操作一个类的实例对象,线程甲此时进入transfer()方法,拿到了对象的锁,他便开始运行代码,然后,他会调用一个方法getTotalBalance(),问题就出来了,那么这个方法需要同步吗? 如小范所说,可以不用同步,因为这个方法是在甲拿到锁之后,释放锁之前调用的,他是同步的,也就是说线程甲必须执行完这个方法,如果transfer()还需要调用其他方法,那个方法也必须被执行完,依次类推。 接下来的问题,如果getTotalBalance()里面也调用了Lock.lock()呢? 好的,这样也是可以的,因为一个线程可以对同一对象多次上锁,如果getTotalBalance()里面被线程上了锁,他执行完之后这个锁必须被释放,对于每一个对象,虚拟机会有一个加锁计数器,你加一次锁,计数加一,一个对象的锁真正被释放就意味着计数器必须为0(我还不清楚加锁和解锁是不是必须要对应),我的大致想法如下,有什么错误,恳请指出,大家一起学习!