`
wanxiaotao12
  • 浏览: 484177 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

浅谈多线程中的同步锁

 
阅读更多

转:http://wenjuema.iteye.com/blog/660705

 

多线程应用中,我们往往会对同一对象或类进行操作,这时我们需要应用同步锁,以保证程序的正常运行。本文将从Synchronized, wait, notify这些Java常见的关键字/函数作为出发点,总结同步与锁的问题,适合Java初级者阅读解惑。

 

一. synchronized关键字。

 

为啥同步?简单来讲,一个线程在对某对象操作时,不想被其他线程的同步方法所干扰。

 

在实际编程中,我们有两种方式实现同步,分别是同步方法(synchronized methods)或同步块(synchronized block/synchronized statement)。

 

同步方法是在方法前加synchronized, 如果该方法是static的,则认为锁是相对于Class的,其他线程操作该类的任何对象时,遇到static同步方法或者方法内同步该Class时,需要等待;若该方法不是static的,则认为锁是相对于自身对象(this)的,其他线程操作此对象时,遇到同步方法(非static),需要等待。

 

同步块一般写在函数里,形式如下:

模式代码 复制代码 收藏代码
  1. synchronized ( Expression ) Block
synchronized ( Expression ) Block


Expression需是引用类型(对象,类), Block则是代码块。同步块开始时需要获得Expression的一个互斥锁(mutual-exclusion lock)。当该锁没被其他线程占用时,获取该锁并则执行Block里内容,在Block结束后释放此锁。在执行Block时,任何其他想要获得该锁的线程需要阻塞等待。

 

[注意点]


1. 可以认为锁是属于引用类型的, 同步的操作需要获取锁之后才进行,否则一直等待。编程时需注意锁(synchronized)的对象

 

2. 线程在wait后会释放持有的锁。有关wait详细说明参见本文第二部分。

 

3. 各线程同步时遵守先触发,先得锁原则(happens-before relationship)。

 

4. 构造函数无法被synchronized。

 


二. wait(), notify(), notifyAll()

 

wait, notify, notifyAll方法均定义在基类Object中,它们的职责是为了在多线程中,可以有效的进行线程间交互,或者控制转移。一个线程执行了wait, 需要其他线程notify,或者notifyAll, 才可以继续执行。举个例子,消费者和生产者,当没有Message被生产者生产时,消费者则一直处于wait状态,直到生产者生产了一条Message,然后notify消费者进行消费。

 

[注意点]

 

1. wait, notify, notifyAll必须在synchronized代码内。即该线程持有了某引用的锁时,wait, notify, notifyAll才可以被执行,否则,会报IllegalMonitorStateException

 

如以下代码(针对wait的,notify, notifyAll同理):

 

Java代码 复制代码 收藏代码
  1. // 会抛IllegalMonitorStateException异常, 因为没持有this的锁。
  2. this.wait();
  3. synchronized(this) {
  4. // 正确写法
  5. this.wait();
  6. // 会抛IllegalMonitorStateException异常, 因为没有持有a对象的锁。
  7. this.a.wait();
  8. }
// 会抛IllegalMonitorStateException异常, 因为没持有this的锁。
this.wait();

synchronized(this) {

    // 正确写法
    this.wait();

    // 会抛IllegalMonitorStateException异常, 因为没有持有a对象的锁。
    this.a.wait();
}

 

2. 执行wait()后会释放锁持有的锁,其他等待同步中的线程这时会持有该锁,并执行。

 

3. wait()执行后,线程状态会变为disabled, 想继续执行除非以下事件中的一个发生:

 

a)其他线程在此同步的引用上执行了notify()或者notifyAll(),注意是和wait相同引用上执行的notify()。

b)线程被其他线程中断,会报InterruptedException。

c)wait可以指定timeout, 当timeout时间过去时。

 

4. wait继续执行需要重新获得该引用的锁,若有其他线程占有着此锁,则仍然无法恢复。

 

5. notify是随机唤醒一个wait中的线程,notifyAll是把所有wait中的线程全部唤醒。notify的对象仍旧是其持有的锁的引用。

 

6. 如果没有线程wait, notify将会被忽略。

分享到:
评论

相关推荐

    浅谈多线程_让程序更高效的运行

    【多线程】是计算机编程中的一个重要概念,它允许程序在同一时间内执行多个任务,从而提高了程序的执行效率。在Java中,多线程是通过创建并运行多个线程来实现的,每个线程代表着进程中的一条独立控制流。Java线程是...

    浅谈多线程中的锁的几种用法总结(必看)

    "浅谈多线程中的锁的几种用法总结" 多线程编程中,锁机制是一种常见的同步机制,用于解决多线程之间的资源竞争问题。锁机制可以分为两种:互斥锁和读写锁。在 Java 中,ReentrantLock 和 ReentrantReadWriteLock 是...

    浅谈Java多线程编程.pdf

    "浅谈Java多线程编程" 从标题和描述可以看出,这篇文章的主题是讨论Java多线程编程的相关知识点。 多线程编程的概念 Java语言的一个重要特点是支持多线程机制,这使得Java程序可以支持多程序并发执行,从而提高...

    浅谈JAVA中多线程的实现.zip

    在Java编程语言中,多线程是程序设计中的一个重要概念,尤其在开发高效能、响应迅速的应用时。本文将深入探讨Java中多线程的实现,帮助开发者理解如何利用这一特性来优化应用程序。 多线程是指在一个程序中同时运行...

    浅谈Linux下的多线程编程.pdf

    - 线程同步是多线程编程中的重要概念,用于避免数据竞争和死锁等问题。`pthread_mutex`提供了互斥锁机制,确保同一时间只有一个线程可以访问临界区。 - 条件变量(`pthread_cond`)允许线程等待特定条件满足后再...

    浅谈Java的多线程机制.pdf

    ### 浅谈Java的多线程机制 #### 一、引言 随着计算机技术的不断发展,编程模型变得越来越复杂和多样化。多线程编程模型作为目前计算机系统架构中的一个重要组成部分,其重要性日益凸显。特别是在X86架构的硬件成为...

    浅谈linux多线程编程和windows多线程编程的异同.doc

    无论是Linux还是Windows,多线程编程的一个主要挑战是线程同步。当多个线程访问同一资源时,必须避免竞态条件和死锁。在Windows中,除了互斥量,还有事件对象(Event)、信号量(Semaphore)和临界区(Critical ...

    浅谈.Net下的多线程和并行计算(全集)

    在.NET框架中,多线程和并行计算是提高应用程序性能和响应能力的关键技术。本文将深入探讨这两个概念,以及如何在.NET环境下有效地利用它们。 首先,多线程是指一个程序中同时执行多个独立的线程,每个线程都有自己...

    浅谈.doclinux.doc多线程编程和.docwindows.doc多线程编程的异同.doc

    多线程编程是一种在单个进程中同时执行多个并发任务的技术,它可以提高程序的效率和响应性,尤其是在处理大型计算任务或需要并行处理的场景中。本文将对比Linux和Windows平台上的多线程编程,探讨它们的异同点。 ...

    浅谈Linux操作系统下的多线程编程.pdf

    在多线程环境中,同步和互斥是保证数据一致性的重要手段。线程间的同步可以通过条件变量(`pthread_cond_t`)和互斥锁(`pthread_mutex_t`)来实现。互斥锁用于保护共享资源,确保同一时间只有一个线程访问;条件...

    浅谈Java多线程实现及同步互斥通讯

    浅谈Java多线程实现及同步互斥通讯 多线程实现方式: Java中的多线程实现方式共有两种:通过继承Thread类和通过实现Runnable接口。下面我们来详细了解这两种方式: 1. 通过继承Thread类来实现多线程: 通过继承...

    浅谈iOS中的锁的介绍及使用

    在iOS开发中,多线程技术常常用于提升应用程序的响应速度和用户体验,但在并发执行时,资源竞争问题可能会导致数据不一致或者程序错误。为了解决这个问题,我们需要确保线程安全,即在同一时刻只有一个线程能访问...

    浅谈Python线程的同步互斥与死锁

    Python线程的同步互斥与死锁是多线程编程中的关键概念,它们涉及到线程间的协调和资源管理,以确保程序的正确性和高效性。本文将深入探讨这些主题,并提供相关的示例代码来帮助理解。 首先,线程间通信是多线程编程...

    Java同步机制浅谈

    `synchronized`关键字主要用于解决Java应用程序中的多线程同步问题。它可以应用于方法和代码块,帮助开发者控制对共享资源的访问,从而保证数据的一致性和安全性。 1. **同步方法**:当`synchronized`关键字用于...

    浅谈Java多线程编程中Boolean常量的同步问题

    在Java多线程编程中,确保...总之,Java多线程编程中,对`Boolean`常量的同步必须谨慎处理,避免因为自动装箱和对象引用的特性导致的同步失效。通过正确理解和使用同步机制,我们可以确保多线程环境下的数据一致性。

    浅谈java多线程wait,notify

    在Java多线程编程中,wait和notify是两个非常重要的机制,用于实现线程之间的通信和同步。在本文中,我们将通过示例代码详细介绍Java多线程wait和notify的使用,帮助读者更好地理解和掌握这两个机制。 wait机制 在...

    浅谈分布式锁

    分布式锁是解决分布式系统中多个进程间共享资源互斥访问的一种方法,它保证了即使在分布式环境下,也能维持数据的一致性。随着互联网公司业务的不断扩展和技术的进步,分布式系统的数据量和业务复杂性大幅增加,...

    浅谈python多线程和多线程变量共享问题介绍

    在Python中,多线程是一种实现并发编程的重要方式。它允许程序在单个进程中创建多个线程来执行不同的任务,从而提高程序的执行效率。Python标准库中的`threading`模块提供了丰富的接口来创建和管理线程。 #### 二、...

Global site tag (gtag.js) - Google Analytics