多线程的同步锁问题

问题描述

首先,祝大家伙节日快乐大过节的,又要麻烦大家了。不过,我觉得这是很经典的一个例子,希望大伙能一起瞧瞧

我先说明一下意思银行类里面有两个方法,transfer()和getTotalBalance()他们用的是同一把锁,在实例化该类的时候产生我的主要困惑在于,当一个线程进入transfer()方法的时候,他获得了锁,但是他同时调用了getTotalBalance()方法System.out.printf("TotalBalance:%10.2f%n",getTotalBalance());可是,这个方法也是需要锁的,而且他们用的是同一把锁publicdoublegetTotalBalance(){Bank_TestLock.lock();try{doublesum=0;for(doublea:accounts)sum+=a;returnsum;}finally{Bank_TestLock.unlock();}}那么,当我执行上面代码的时候,到底发生了什么呢,还请大侠们明示!

解决方案

解决方案二:
lock/unlock里面的内容是什么啊?
解决方案三:
锁的含义,相信你是明白的,锁是为了独占某个资源,当A资源被占用之后,如果有别的线程希望占用A资源,那么就需要等到资源释放.在这里的话,当你执行getTotalBlance就是代表着,当你计算总收支平衡的时候,不允许对账户进行操作,以避免你计算错误,例如甲乙两个账户,你计算了甲账户之后,从甲账户汇了钱到乙账户,如果你不暂停对所有账户的操作,那么你在计算乙账户的时候,重复的计算了刚汇来的那笔钱,得到的结果就是错误的
解决方案四:
兄台,你的意思我明白。我分析一下思路吧,当甲调用了transfer方法,获得了锁,他在里面进行了汇款给乙,甲的钱少了,乙的钱多了,然后他想计算总的存款量,他又要调用getTotalBalance()方法,这个方法也是需要锁的,可是甲的锁是在finally里面释放的(见代码),那么甲进入getTotalBalance()方法的时候,他获取的是哪一把锁呢。我这里的锁是基于Bank_Test的某一个实例的,因为甲,乙是操作的同一个实例的内容,所以肯定是用的同一把锁我的主要困惑是,在调用getTotalBalance()方法的时候怎么去理解甲的锁还没有释放,还请兄台明示!
解决方案五:
引用3楼HOLLYWOOD2012的回复:

兄台,你的意思我明白。我分析一下思路吧,当甲调用了transfer方法,获得了锁,他在里面进行了汇款给乙,甲的钱少了,乙的钱多了,然后他想计算总的存款量,他又要调用getTotalBalance()方法,这个方法也是需要锁的,可是甲的锁是在finally里面释放的(见代码),那么甲进入getTotalBalance()方法的时候,他获取的是哪一把锁呢。我这里的锁是基于Bank_Test的某一个实例的,因为甲,乙是操作的同一个实例的内容,所以肯定是用的同一把锁我的主要困惑是,在调用getTotalBalance()方法的时候怎么去理解甲的锁还没有释放,还请兄台明示!

你可以理解为,在getTotalBalance()中,我们去想系统申请说,诶,系统,我要一个人占用某个资源;如果系统中有人已经占用了,然后系统就说,现在有人在使用,你先等着吧,然后我们就只要在那儿等着系统释放资源,然后拿到了系统的允许之后再向下执行
解决方案六:
楼主能解释下具体解释下什么意思吗?当一个线程进入transfer()方法的时候,他获得了锁。获得了哪个对象的锁?这个银行类需要操作具体的客户类?获得的锁是什么锁。
解决方案七:
晕,现在才出现代码
解决方案八:
请别截图好么使用代码格式粘贴,大家都会很好看。复制代码放到那个两个code标签之间,就这么简单。
解决方案九:
引用一下楼主的原话我的主要困惑在于,当一个线程进入transfer()方法的时候,他获得了锁,但是他同时调用了getTotalBalance()方法System.out.printf("TotalBalance:%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(我还不清楚加锁和解锁是不是必须要对应),我的大致想法如下,有什么错误,恳请指出,大家一起学习!
解决方案十一:
楼主是来给大家讲课还是来问问题啊?
解决方案十二:
引用8楼u010342936的回复:

引用一下楼主的原话我的主要困惑在于,当一个线程进入transfer()方法的时候,他获得了锁,但是他同时调用了getTotalBalance()方法System.out.printf("TotalBalance:%10.2f%n",getTotalBalance());可是,这个方法也是需要锁的,而且他们用的是同一把锁。。。。。。那么,当我执行上面代码的时候,到底发生了什么呢,还请大侠们明示!你是没理解清楚同步锁的含义。首先,是线程获取锁,而不是transfer()或者是getTotalBalance()方法获取锁。理论上来说,一个线程可以多次对同一个对象上锁。对于每一个对象,java虚拟机维护一个加锁计数器,线程每获得一次该对象,计数器就加1,每释放一次,计数器就减1,当计数器值为0时,锁就被完全释放了。所以,是这个线程获取了同一个对象的两次锁。你问会发生什么?答案是:在同一个线程中transfer()和getTotalBalance()方法不会起到同步的效果。代码跑到哪里就运行什么,第二次look是没效果的。为什么说是理论上呢?因为我实在想不出你的look/unlook代码是怎么写的。。。我想到的线程同步,首先是synchronized关键字。你这look/unlook用法,怎么看也不像是用synchronized关键字。

首先比较同意是线程获取了锁,lock是一把锁多个监视器,这个比synchronized强大了很多,但是似乎也麻烦了不少了,synchronized将同步和锁绑定在一起了。

时间: 2024-09-10 18:59:30

多线程的同步锁问题的相关文章

多线程 java 同步 锁-java中多线程访问同步问题

问题描述 java中多线程访问同步问题 public class SyschronizedSample{ private int value; public synchronized int get(){ return value;} public synchronized void set(int value) { this.value=value; } } 以上的代码中,要使得访问value时具有线程安全,所以在set和get方法中都加了synchronized同步语句,如果只在set方法前

Java多线程:“JUC锁”01之框架

根据锁的添加到Java中的时间,Java中的锁,可以分为"同步锁"和 "JUC包中的锁". 同步锁 即通过synchronized关键字来进行同步,实现对竞争资源的互斥访问的锁.Java 1.0版本中就已经支 持同步锁了. 同步锁的原理是,对于每一个对象,有且仅有一个同步锁:不同的线程能共同访问该同步锁.但是, 在同一个时间点,该同步锁能且只能被一个线程获取到.这样,获取到同步锁的线程就能进行CPU调度, 从而在CPU上执行:而没有获取到同步锁的线程,必须进行等待,

Java多线程的同步示例及对象锁机制

java多线程的同步依靠的是对象锁机制,synchronized关键字的背后就是利用了封锁来实现对共享资源的互斥访问. 下面以一个简单的实例来进行对比分析.实例要完成的工作非常简单,就是创建10个线程,每个线程都打印从0到99这100个数字,我们希望线程之间不会出现交叉乱序打印,而是顺序地打印. 先来看第一段代码,这里我们在run()方法中加入了synchronized关键字,希望能对run方法进行互斥访问,但结果并不如我们希望那样,这 是因为这里synchronized锁住的是this对象,即

java-Java中多线程同步锁报无效指针异常是何原因,求大神解答!

问题描述 Java中多线程同步锁报无效指针异常是何原因,求大神解答! /* 需求: 使用lock接口实现商品的生产和销售的动态平衡 思路: 1.创建被共同操作的数据类Resource,并通过多态引用分别创建lock和condition子类对象以及资源的获取和赋值方法 2.创建两个相反操作即生产和销售的类同时实现Runnable接口,并覆盖run方法 3.在主函数中,创建资源对象,并作为共同参数分别传递给生产和销售两个线程实现类的构造函数 4.分别将生产和销售类的对象作为参数,传给两个线程,并各自

起底多线程同步锁(iOS)

iOS/MacOS为多线程.共享内存(变量)提供了多种的同步解决方案(即同步锁),对于这些方案的比较,大都讨论了锁的用法以及锁操作的开销,然后就开销表现排个序.小哥以为,最优方案的选用还是看应用场景,高频接口PK低频接口.有限冲突PK激烈竞争.代码片段耗时的长短,以上都是正确选用的重要依据,不同方案在其适用范围表现各有不同.这些方案当中,除了熟悉的iOS/MacOS系统自有的同步锁,另外还有两个自研的读写锁,还有应用开发中常见的set/get访问接口的原子操作属性. 1.@synchronize

java多线程的同步与多线程锁介绍

线程的同步和锁的问题,我们先来看个例子, 下面的例子我们希望两个线程对m变量进行削减  代码如下 复制代码 packagecom.javaer.thread;  publicclassSysTestimplementsRunnable{ intm=10; publicstaticvoidmain(String[]args){ SysTests1=newSysTest(); Threadt1=newThread(s1,"Thread-t1"); Threadt2=newThread(s1

.NET中多线程的同步资源访问

在应用程序中使用多个线程的一个好处是每个线程都可以异步执行.对于 Windows 应用程序,耗时的任务可以在后台执行,而使应用程序窗口和控件保持响应.对于服务器应用程序,多线程处理提供了用不同线程处理每个传入请求的能力.否则,在完全满足前一个请求之前,将无法处理每个新请求.然而,线程的异步特性意味着必须协调对资源(如文件句柄.网络连接和内存)的访问.否则,两个或更多的线程可能在同一时间访问相同的资源,而每个线程都不知道其他线程的操作.结果将产生不可预知的数据损坏. 让我们先来看一片java的例子

springmvc-java 多用户线程同步锁

问题描述 java 多用户线程同步锁 SSM 框架做一个用户取钱的业务,为了防止一个用多端同时取钱, 可以再业务方法前加上synchronized 是方法变成同步方法,每一个请求经过这个业务方法是只能同步等待, 但是如果有很多个用户同时取钱呢(,本来不同的用户取钱时不会相互影响的,) 如果这样做就会降低程序的执行效率, 请问谁知道怎么做? 解决方案 线程锁的时间可以忽略不计吧?有确切测试证明会影响用户使用吗? 解决方案二: 首先,Java web请求处理是多线程的,即每个请求都是由一个线程来处理

请问多线程的同步和串行有什么区别

问题描述 请问多线程的同步和串行有什么区别 如果一段代码被锁住执行完再去执行另一段代码,这和顺序执行有什么区别呢,求各位大神解答啊 解决方案 没错,同步的代码,从本质上说,相当于串行(非并发)执行. 解决方案二: 多线程只有同步和异步之分,没有同步和串行. 串行一般只代码一行行有序执行.至于同步异步实际不关心. 解决方案三: 我的意思是如果同步了,不就跟顺序执行一个意思了么,执行完一个块再执行另一个块,那这样的话多线程的同步实际上没有实现并发啊,这个时候的多线程是为了什么呢 解决方案四: 其实多