`

Java 多线程同步 锁机制与synchronized

 
阅读更多

打个比方:一个object就像一个大房子,大门永远打开。房子里有很多房间(也就是方法)。这些房间有上锁的(synchronized方法), 和不上锁之分(普通方法)。房门口放着一把钥匙(key),这把钥匙可以打开所有上锁的房间。 另外我把所有想调用该对象方法的线程比喻成想进入这房子某个 房间的人。所有的东西就这么多了,下面我们看看这些东西之间如何作用的。

在此我们先来明确一下我们的前提条件 。该对象至少有一个synchronized方法,否则这个key还有啥意义。当然也就不会有我们的这个主题了。

一个人想进入某间上了锁的房间,他来到房子门口,看见钥匙在那儿(说明暂时还没有其他人要使用上锁的房间)。于是他走上去拿到了钥匙,并且按照自己 的计划使用那些房间。注意一点,他每次使用完一次上锁的房间后会马上把钥匙还回去 即使他要连续使用两间上锁的房间,中间他也要把钥匙还回去,再取回来。

  因此,普通情况下钥匙的使用原则是:“随用随借,用完即还。”

  这时其他人可以不受限制的使用那些不上锁的房间,一个人用一间可以,两个人用一间也可以,没限制。但是如果当某个人想要进入上锁的房间,他就要跑到大门口去看看了。有钥匙当然拿了就走,没有的话,就只能等了。

要 是很多人在等这把钥匙,等钥匙还回来以后,谁会优先得到钥匙?Not guaranteed。象前面例子里那个想连续使用两个上锁房间的家伙,他中间还钥匙的时候如果还有其他人在等钥匙,那么没有任何保证这家伙能再次拿到。 (JAVA规范在很多地方都明确说明不保证,象Thread.sleep()休息后多久会返回运行,相同优先权的线程那个首先被执行,当要访问对象的锁被 释放后处于等待池的多个线程哪个会优先得到,等等。我想最终的决定权是在JVM,之所以不保证,就是因为JVM在做出上述决定的时候,绝不是简简单单根据 一个条件来做出判断,而是根据很多条。而由于判断条件太多,如果说出来可能会影响JAVA的推广,也可能是因为知识产权保护的原因吧。SUN给了个不保证 就混过去了。无可厚非。但我相信这些不确定,并非完全不确定。因为计算机这东西本身就是按指令运行的。即使看起来很随机的现象,其实都是有规律可寻。学过 计算机的都知道,计算机里随机数的学名是伪随机数,是人运用一定的方法写出来的,看上去随机罢了。另外,或许是因为要想弄的确定太费事,也没多大意义,所 以不确定就不确定了吧。)

  再来看看同步代码块。 和同步方法有小小的不同。

  1.从尺寸上讲,同步代码块比同步方法小。你可以把同步代码块看成是没上锁房间里的一块用带锁的屏风隔开的空间。

  2.同步代码块还可以人为的指定获得某个其它对象的key。就像是指定用哪一把钥匙才能开这个屏风的锁,你可以用本房的钥匙;你也可以指定用另一个房子的钥匙才能开,这样的话,你要跑到另一栋房子那儿把那个钥匙拿来,并用那个房子的钥匙来打开这个房子的带锁的屏风。

      记住你获得的那另一栋房子的钥匙,并不影响其他人进入那栋房子没有锁的房间。

      为什么要使用同步代码块呢?我想应该是这样的:首先对程序来讲同步的部分很影响运行效率,而一个方法通常是先创建一些局部变量,再对这些变量做一些 操作,如运算,显示等等;而同步所覆盖的代码越多,对效率的影响就越严重。因此我们通常尽量缩小其影响范围。如何做?同步代码块。我们只把一个方法中该同 步的地方同步,比如运算。

      另外,同步代码块可以指定钥匙这一特点有个额外的好处,是可以在一定时期内霸占某个对象的key。还记得前面说过普通情况下钥匙的使用原则吗。现在不是普通情况了。你所取得的那把钥匙不是永远不还,而是在退出同步代码块时才还。

      还用前面那个想连续用两个上锁房间的家伙打比方。怎样才能在用完一间以后,继续使用另一间呢。用同步代码块吧。先创建另外一个线程,做一个同步代码 块,把那个代码块的锁指向这个房子的钥匙。然后启动那个线程。只要你能在进入那个代码块时抓到这房子的钥匙,你就可以一直保留到退出那个代码块。也就是说 你甚至可以对本房内所有上锁的房间遍历,甚至再sleep(10*60*1000),而房门口却还有1000个线程在等这把钥匙呢。很过瘾吧。

     在此对sleep()方法和钥匙的关联性讲一下。一个线程在拿到key后,且没有完成同步的内容时,如果被强制sleep()了,那key还一直在 它那儿。直到它再次运行,做完所有同步内容,才会归还key。记住,那家伙只是干活干累了,去休息一下,他并没干完他要干的事。为了避免别人进入那个房间 把里面搞的一团糟,即使在睡觉的时候他也要把那唯一的钥匙戴在身上。

      最后,也许有人会问,为什么要一把钥匙通开,而不是一个钥匙一个门呢?我想这纯粹是因为复杂性问题。一个钥匙一个门当然更安全,但是会牵扯好多问题。钥 匙的产生,保管,获得,归还等等。其复杂性有可能随同步方法的增加呈几何级数增加,严重影响效率。这也算是一个权衡的问题吧。为了增加一点点安全性,导致 效率大大降低,是多么不可取啊。

1.示例题目

pulbic class Something(){
          public synchronized void isSyncA(){}
          public synchronized void isSyncB(){}
          public static synchronized void cSyncA(){}
          public static synchronized void cSyncB(){}
      }
    那么,加入有Something类的两个实例a与b,那么下列组方法何以被1个以上线程同时访问呢
    a.   x.isSyncA()与x.isSyncB() 
    b.   x.isSyncA()与y.isSyncA()
    c.   x.cSyncA()与y.cSyncB()
    d.   x.isSyncA()与Something.cSyncA()

 a,都是对同一个实例的synchronized域访问,因此不能被同时访问
 b,是针对不同实例的,因此可以同时被访问
 c,因为是static synchronized,所以不同实例之间仍然会被限制,相当于Something.isSyncA()与   Something.isSyncB()了,因此不能被同时访问。
 那么,第d呢?,书上的 答案是可以被同时访问的,答案理由是synchronzied的是实例方法与synchronzied的类方法由于锁定(lock)不同的原因。

2.synchronized方法与synchronized代码快的区别
synchronized methods(){} 与synchronized(this){}之间没有什么区别,只是 synchronized methods(){} 便于阅读理解,而synchronized(this){}可以更精确的控制冲突限制访问区域,有时候表现更高效率。

3.synchronized不能继承,子类的覆盖方法必须显示的将其定义成synchronized,此时,子类调用父类的方法属于内部锁,内部锁可重入

写代码得多加注意,多加注意

分享到:
评论

相关推荐

    Java 多线程同步 锁机制与synchronized深入解析

    Java中的多线程同步是一种控制并发访问共享资源的方式,以防止数据不一致和线程冲突。锁机制是Java实现同步的主要手段,其中synchronized关键字扮演了核心角色。 synchronized可以用于修饰方法或代码块,两者在锁的...

    java锁机制Synchronizedjava锁机制Synchronized

    Java 锁机制 Synchronized 是 Java 语言中的一种同步机制,用于解决多线程并发访问共享资源时可能出现的一些问题。 Java 锁机制 Synchronized 的概念 在 Java 中,每个对象都可以被看作是一个大房子,其中有多个...

    Java多线程同步机制研究分析.pdf

    Java多线程同步机制有两种类型:synchronized方法和synchronized块。synchronized方法是将访问共享资源的方法标记为synchronized,然后该标记的方法来控制对类成员变量的访问。synchronized块是将程序的某段代码使用...

    Java多线程同步.pdf

    Java多线程同步是指在Java语言中,如何使用synchronized关键字和其他同步机制来确保多线程程序的正确执行。在Java语言中,synchronized关键字用于对方法或者代码块进行同步,但是仅仅使用synchronized关键字还不能...

    Java多线程同步机制的应用分析.pdf

    "Java多线程同步机制的应用分析" Java多线程同步机制的应用分析是指在Java语言中,如何使用同步机制来保护临界区,以避免多线程之间的冲突和错误。该机制通过管程机制和同步语法来保护临界区,使得多线程可以安全...

    java的线程同步机制synchronized关键字的理解_.docx

    Java 线程同步机制中 synchronized 关键字的理解 Java 的线程同步机制是为了解决多个线程共享同一片存储空间所带来的访问冲突问题。其中,synchronized 关键字是 Java 语言中解决这种冲突的重要机制。 ...

    JAVA多线程的锁机制和无锁并行.docx

    JAVA 多线程的锁机制和无锁并行 JAVA 多线程编程中,锁机制是保证线程安全的重要手段之一。锁机制可以分为内部锁和外部锁两种,内部锁又称为监视器或内部锁,它是一种非公平的排它锁,能够保障原子性、可见性和...

    基于Java多线程同步的安全性研究.pdf

    文章首先介绍了Java多线程同步的必要性和重要性,然后讨论了Java多线程同步机制的实现方法,包括使用synchronized关键字和Java.util.concurrent.locks包中的Lock对象。接着,文章讨论了Java多线程同步机制中可能出现...

    java 多线程synchronized互斥锁demo

    标题中的"java 多线程synchronized互斥锁demo"指的是一个示例,展示了如何在多线程环境下使用`synchronized`关键字创建互斥锁,确保同一时间只有一个线程可以访问特定的代码块或方法。 描述中的"一个多线程访问的同...

    java多线程之并发锁

    Java 中的多线程编程需要充分考虑线程安全和锁机制的问题,否则可能会导致程序的执行不稳定和崩溃。Lock 机制是 Java 中的一种重要的线程同步机制,它可以用来实现线程安全和提高程序的执行效率。

    基于Java并发编程的多线程同步与锁机制.zip

    基于Java并发编程的多线程同步与锁机制 项目简介 本项目旨在深入探讨Java并发编程中的多线程同步与锁机制,涵盖了从基础的线程创建、同步方法到高级的并发工具类如ReentrantLock、ReadWriteLock、Atomic类等的...

    java多线程、锁的教程跟案例

    Java多线程与锁是Java并发编程中的核心概念,它们对于构建高效、可扩展的并发应用程序至关重要。在Java中,多线程允许程序同时执行多个任务,提高CPU的利用率,而锁则是用来控制多线程间共享资源的访问,确保数据的...

    Java多线程同步机制在售票系统的实现

    ### Java多线程同步机制在售票系统的实现 #### 一、引言 随着计算机硬件的发展,多核处理器已经成为主流配置,这为多线程编程提供了更广阔的应用场景。多线程能够充分利用多核处理器的优势,提高程序的并发性和...

    Java多线程同步具体实例讲解 .doc

    总结起来,Java多线程同步是通过`synchronized`关键字实现的,它可以应用于方法或代码块,保证同一时刻只有一个线程能够执行特定的代码。通过合理使用同步机制,开发者可以有效地管理并发程序中的资源访问,避免数据...

    21.线程的同步机制-synchronized同步方法-锁自动释放.mp4

    在学习Java过程中,自己收集了很多的Java的学习资料,分享给大家,有需要的欢迎下载,希望对大家有用,一起学习,一起进步。

    java 多线程同步

    Java多线程同步是Java编程中关键的并发概念,它涉及到如何在多个线程访问共享资源时保持数据的一致性和完整性。`java.util.concurrent`包是Java提供的一个强大的并发工具库,它为开发者提供了多种线程安全的工具,...

    Java多线程-同步机制解决线程安全问题方式一:同步代码块

    Java多线程编程中,线程安全问题是常见的挑战,特别是在并发环境下,多个线程可能会同时访问和修改同一份共享资源,导致数据不一致。为了解决这个问题,Java提供了同步机制,其中一种常用的方式就是同步代码块...

    java 多线程同步方法的实例

    在Java编程语言中,多线程同步是一种控制多个线程并发执行的重要机制,它确保了共享资源的安全访问,防止数据不一致性和竞态条件的发生。本文将深入探讨Java中的多线程同步方法,并通过实例来阐述其工作原理。 首先...

Global site tag (gtag.js) - Google Analytics