`
johanyi
  • 浏览: 5093 次
  • 性别: Icon_minigender_1
  • 来自: 大连
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

Java同步机制总结–synchronized

阅读更多
不久前用到了同步,现在回过头来对JAVA中的同步做个总结,以对前段时间工作的总结和自我技术的条理话。JAVA中synchronized关键字能够作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法和同步语句块。假如再细的分类,synchronized可作用于instance变量、object reference(对象引用)、static函数和class literals(类名称字面常量)身上。
在进一步阐述之前,我们需要明确几点:
A.无论synchronized关键字加在方法上还是对象上,他取得的锁都是对象,而不是把一段代码或函数当作锁――而且同步方法很可能还会被其他线程的对象访问。
B.每个对象只有一个锁(lock)和之相关联。
C.实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。
接着来讨论synchronized用到不同地方对代码产生的影响:

假设P1、P2是同一个类的不同对象,这个类中定义了以下几种情况的同步块或同步方法,P1、P2就都能够调用他们。

1.  把synchronized当作函数修饰符时,示例代码如下:
Public synchronized void method(){
//….
}
这也就是同步方法,那这时synchronized锁定的是哪个对象呢?他锁定的是调用这个同步方法对象。也就是说,当一个对象P1在不同的线程中执行这个同步方法时,他们之间会形成互斥,达到同步的效果。但是这个对象所属的Class所产生的另一对象P2却能够任意调用这个被加了synchronized关键字的方法。
上边的示例代码等同于如下代码:
public void method()
{
synchronized (this)      //  (1)
{
//…..
}
}
(1)处的this指的是什么呢?他指的就是调用这个方法的对象,如P1。可见同步方法实质是将synchronized作用于object reference。――那个拿到了P1对象锁的线程,才能够调用P1的同步方法,而对P2而言,P1这个锁和他毫不相干,程式也可能在这种情形下摆脱同步机制的控制,造成数据混乱:(
2.同步块,示例代码如下:
public void method(SomeObject so) {
synchronized(so)
{
//…..
}
}
这时,锁就是so这个对象,谁拿到这个锁谁就能够运行他所控制的那段代码。当有一个明确的对象作为锁时,就能够这样写程式,但当没有明确的对象作为锁,只是想让一段代码同步时,能够创建一个特别的instance变量(他得是个对象)来充当锁:
class Foo implements Runnable
{
private byte[] lock = new byte[0];  // 特别的instance变量
Public void method()
{
synchronized(lock) { //… }
}
//…..
}
注:零长度的byte数组对象创建起来将比任何对象都经济――查看编译后的字节码:生成零长度的byte[]对象只需3条操作码,而Object lock = new Object()则需要7行操作码。
3.将synchronized作用于static 函数,示例代码如下:
Class Foo
{
public synchronized static void method1()   // 同步的static 函数
{
//….
}
public void method2()
{
synchronized(Foo.class)   //  class literal(类名称字面常量)
}
}
代码中的method2()方法是把class literal作为锁的情况,他和同步的static函数产生的效果是相同的,取得的锁很特别,是当前调用这个方法的对象所属的类(Class,而不再是由这个Class产生的某个具体对象了)。
记得在《Effective Java》一书中看到过将 Foo.class和 P1.getClass()用于作同步锁还不相同,不能用P1.getClass()来达到锁这个Class的目的。P1指的是由Foo类产生的对象。
能够推断:假如一个类中定义了一个synchronized的static函数A,也定义了一个synchronized 的instance函数B,那么这个类的同一对象Obj在多线程中分别访问A和B两个方法时,不会构成同步,因为他们的锁都不相同。A方法的锁是Obj所属的那个Class,而B的锁是Obj所属的这个对象。

小结如下:
搞清楚synchronized锁定的是哪个对象,就能帮助我们设计更安全的多线程程式。

更有一些技巧能够让我们对共享资源的同步访问更加安全:
1.  定义private 的instance变量+他的 get方法,而不要定义public/protected的instance变量。假如将变量定义为public,对象在外界能够绕过同步方法的控制而直接取得他,并改变他。这也是JavaBean的标准实现方式之一。
2.  假如instance变量是个对象,如数组或ArrayList什么的,那上述方法仍然不安全,因为当外界对象通过get方法拿到这个instance对象的引用后,又将其指向另一个对象,那么这个private变量也就变了,岂不是很危险。 这个时候就需要将get方法也加上synchronized同步,并且,只返回这个private对象的clone()――这样,调用端得到的就是对象副本的引用了。

本文转载自推酷网,原文链接:http://www.tuicool.com/articles/JJZNRr
分享到:
评论

相关推荐

    Core Java™ Volume II–Advanced Features, Eighth Edition

    书中可能会详细介绍`Thread`类、`Runnable`接口、同步机制(如`synchronized`关键字,`wait()`, `notify()`和`notifyAll()`方法)、线程池以及并发工具类(如`ExecutorService`和`Future`)。 2. 高级IO/NIO:Java...

    Java中的同步与互斥机制–synchornized学习

    `synchronized` 关键字是Java提供的一个内置锁机制,用于实现线程间的同步和互斥。 1. **synchronized 作为函数修饰符** 当`synchronized` 修饰非静态方法时,它锁定的是调用该方法的对象。这意味着,如果有多个...

    java中Locks的使用详解

    在 Java 中,Locks 是一种非常重要的同步机制,它提供了更加灵活的同步控制。在 Java 5 中,Locks 被引入,以提供更加灵活的同步控制。与 Synchronized Block 相比,Locks 提供了更加灵活的同步控制。 Lock 和 ...

    多线程–Synchronized

    `synchronized`通过控制对特定代码块或方法的访问,确保了在同一时刻只有一个线程可以执行这部分代码,从而提供了一种线程互斥机制。 1. **原子性**:`synchronized`保证了同步代码块或同步方法的执行具有原子性,...

    Introduction to Java Programming(10th Edition)课后练习答案

    了解如何创建线程(通过Thread类或实现Runnable接口)、同步机制(synchronized关键字、wait()、notify()、notifyAll()方法)以及线程池的概念。 7. **反射与注解**:反射机制允许程序在运行时动态获取类的信息并...

    Core JAVA II. 8th (英文版.JAVA核心技术.第8版.卷二高级篇)

    - **同步机制**:介绍如何利用`synchronized`关键字和其他同步工具如`ReentrantLock`来解决线程间的同步问题。 - **并发工具类**:详细解释了`ExecutorService`、`Future`接口以及`CountDownLatch`等高级并发工具的...

    java面试选择题(内部资料)

    根据提供的文档内容,我们可以总结出一系列与Java编程语言相关的知识点,这些知识点主要集中在Java的基本语法、标识符规则、线程管理、关键字理解等方面。下面是基于文档内容的具体知识点解析: ### 1. Java代码的...

    黑马程序员–Java多线程讲解笔记

    在实际开发中,合理地运用多线程和同步机制可以极大地提升程序的并发性能,但也需要注意避免过度使用同步,以免造成线程阻塞,影响程序的整体性能。因此,理解和掌握Java的多线程技术对于任何Java程序员来说都是至关...

    java学习笔记

    - **synchronized同步机制**:`synchronized`关键字用于控制对共享资源的并发访问,可以应用于方法或代码块,确保线程安全。 #### 访问控制与变量声明 - **访问修饰符**:Java提供四种访问级别:`public`(公开)...

    \Sun培训教程.pdf

    - **同步机制**:探讨Java中的同步机制,如synchronized关键字、volatile变量等。 - **并发工具类**:介绍Java并发包中的工具类,如Executor框架、CountDownLatch等。 ##### 6. 网络 - **Socket编程**:教授如何...

    Java_masterclass

    掌握synchronized关键字、wait/notify机制,以及并发工具类如ExecutorService、Semaphore和CyclicBarrier。 7. **网络编程**:学习如何使用Socket进行网络通信,创建客户端和服务端应用程序,理解TCP和UDP协议的...

    java斗地主适合初学者

    - **同步机制**:使用synchronized关键字或Lock接口确保在并发环境下的线程安全,防止数据冲突。 4. **算法设计** - **排序算法**:洗牌时可能需要用到快速排序或 Fisher–Yates shuffle 等算法。 - **决策逻辑*...

    PROJ207_Team6:项目工作坊 – CMPP264 Java 主题

    同步机制在多线程编程中至关重要,以防止数据不一致性和资源竞争。Java提供了多种同步工具,包括`synchronized`关键字(用于方法或代码块),`java.util.concurrent`包下的`Lock`接口及其实现(如`ReentrantLock`)...

    JUC–Atomic原子类

    通过使用`AtomicInteger`,开发者可以编写出高性能、高并发的代码,而无需引入复杂的同步机制,简化了并发编程的复杂性。在实际开发中,根据具体需求,还可以选择其他原子类,如`AtomicLong`、`AtomicBoolean`等,...

    –设计模式–五种实现单例模式的方式

    - 不利于并行编程,如果多个进程或线程需要访问同一个实例,可能会引发同步问题。 4. **注意事项**: - 需要防止反序列化导致的多实例问题。 - 必须考虑到多线程环境下的线程安全问题。 **单例模式的五种实现...

Global site tag (gtag.js) - Google Analytics