`
robertliudeqiang
  • 浏览: 123140 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

java对多个对象加锁

    博客分类:
  • java
阅读更多
java中存在对多个对象加锁的情况,例如: 在银行系统转账时,需要锁定两个账户,这个时候,顺序使用两个synchronized可能存在死锁的情况,在网上搜索到下面的例子:

public class Bank {
	final static Object obj_lock = new Object();

	// Deadlock crisis
	public void transferMoney(Account from, Account to, int number) {
		synchronized (from) {
			synchronized (to) {
				from.debit();
				to.credit();
			}
		}
	}

	// Thread safe
	public void transferMoney2(final Account from, final Account to, int number) {
		class Help {
			void transferMoney2() {
				from.debit();
				to.credit();
			}
		}

		int fromHash = from.hashCode();
		int toHash = to.hashCode();
		if (fromHash < toHash) {
			synchronized (from) {
				synchronized (to) {
					new Help().transferMoney2();
				}
			}
		} else if (toHash < fromHash) {
			synchronized (to) {
				synchronized (from) {
					new Help().transferMoney2();
				}
			}
		} else {
			synchronized (obj_lock) {
				synchronized (to) {
					synchronized (from) {
						new Help().transferMoney2();
					}
				}
			}
		}
	}
}


若操作账户A,B:
1 A的hashCode小于B, 先锁A再锁B
2 B的hashCode小于A, 先锁B再锁A
3 产生的hashCode相等,先锁住一个全局静态变量,在锁A,B

这样就避免了两个线程分别操作账户A,B和B,A而产生死锁的情况。

注意点:
  1 需要为Account对象写一个好的hashCode算法,使得不同账户间产生的hashCode尽量不同。
  2 如果某次产生hashCode相同锁住obj_lock,那么如果有新的操作再次产生相同hashCode,就必须等待前一次操作完成,可能产生性能问题。(这里应该有更好的方法)
分享到:
评论

相关推荐

    java多线程的条件对象和锁对象demo

    本示例"java多线程的条件对象和锁对象demo"着重探讨了如何利用锁对象和条件对象来精细控制线程的执行流程。 首先,我们需要了解Java中的锁对象。Java提供了多种类型的锁,其中最基础的是`synchronized`关键字,它...

    Java双重检查加锁单例模式的详解

    Java双重检查加锁单例模式是一种常用的单例模式实现方法,但是在多线程环境下,它存在一些问题。在这篇文章中,我们将探讨Java双重检查加锁单例模式的详解,包括它的优点和缺点,以及如何正确地使用它。 Java双重...

    Java对象锁和类锁全面解析(多线程synchronize

    2. **修饰静态方法**:等同于对类的Class对象加锁,所有实例共享同一把锁。 3. **修饰代码块**:指定要锁定的对象,只对代码块进行锁定,提高了锁的粒度,降低了锁冲突的可能性。 在实际编程中,合理使用`...

    Java的并发处理方式

    Java 提供了 synchronized 关键字来对对象加锁。加锁的对象将被锁定,其他线程必须等待当前线程释放锁后才能访问该对象。有三种方式使用 synchronized: * 锁住方法:public synchronized void print() {...;} * 锁...

    多线程文件加锁自动定时查询mysql统计数据

    综上所述,"多线程文件加锁自动定时查询mysql统计数据"这个任务涵盖了并发编程、文件系统操作、数据库管理和数据分析等多个IT领域的关键知识点,实现这样的系统需要综合运用多种技术和工具。在实际开发过程中,需要...

    Java多线程编程核心技术_完整版_java_

    Java多线程编程是Java开发中的重要组成部分,它允许程序同时执行多个任务,极大地提高了程序的效率和响应性。在Java中,多线程主要通过继承Thread类或实现Runnable接口来实现。本教程《Java多线程编程核心技术》将...

    java多线程和锁,用于学习参考

    Java多线程与锁是Java并发编程中的核心概念,它们...综上所述,Java多线程和锁是解决并发问题的关键,它们涉及线程创建、管理、同步和通信等多个方面。通过深入学习和实践,开发者能够构建出更加稳定、高效的并发程序。

    深入java并发编程,使用ReentrantLock和 Synchronized加锁

    `synchronized`是Java内置的原生锁,它提供了对方法或代码块的锁定,使得在任何时刻只有一个线程能够执行特定的代码。synchronized有以下特性: 1. **互斥性**:当一个线程进入一个由synchronized修饰的方法或代码...

    java synchronize 线程同步

    Java中的`synchronized`关键字是用于...无论是同步方法还是同步代码块,其核心都是通过对特定对象加锁,实现线程间的同步,防止数据竞争。正确理解和使用`synchronized`可以帮助我们编写出更加安全、可靠的多线程程序。

    java+多线程+同步详解Java源码

    Java多线程与同步是Java编程中的核心概念,它们在构建高效、响应迅速的应用程序时起着至关重要的作用。在Java中,多线程允许同时执行多个代码段,从而提高程序的执行效率,特别是在处理I/O密集型或计算密集型任务时...

    java多线程编程总结

    `Thread` 类实例仅仅是Java中的一个对象,具有变量和方法,并存在于堆上。每个Java线程都有自己的调用栈,即使是未显式创建的线程也不例外。主线程是程序开始运行的地方,即从 `main()` 方法启动。一旦创建了一个新...

    java多线程核心编程技术

    - **修饰代码块**:指定加锁对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁。 ##### 3.2 volatile关键字 `volatile`关键字确保变量的可见性和禁止指令重排序。当一个共享变量被volatile修饰时,它会...

    java-os.rar_多进程os

    对临界资源Critical_Resources类进行操作方法声明为synchronized,当方法被该关键字声明后,也就意味着,如果这个资源类被加锁,只有一个对象得到这个类的锁的时候该对象才能对这个类进行操作。这里设置了一个管理...

    高级Java经典面试题2019

    - **并发**:指一个系统内多个进程或线程交替执行的过程,每个任务都可能被执行一小段时间,然后让位给其他任务,使得多个任务看起来同时运行。 - **并行**:指多个任务在同一时刻执行,通常需要多个处理器或者多核...

    2023年Java面试题+详细总结.docx

    fail-fast 是 Java 集合框架中的一个机制,当多个线程对同一个集合的内容进行操作时,就可能会产生 fail-fast 事件。例如:当某一个线程 A 通过 iterator 去遍历某集合的过程中,若该集合的内容被其他线程所改变了;...

    Java问题定位技术(

    多线程编程是Java技术的重要方面,它允许同时执行多个任务,提高程序的执行效率。然而,在多线程环境下,如果不正确使用同步机制,就容易产生死锁、资源竞争等问题。因此,了解在什么情况下需要加锁、如何正确加锁...

    Java多线程高级技术.pdf

    例如,Account类中的deposit()和withdraw()方法都使用了synchronized关键字,以确保对amount变量的访问是同步的,防止多个线程同时对同一个Account对象执行存款和取款操作时发生冲突。 接下来,我们看到了Account类...

    基于Java的多线程技术应用研究

    - **按顺序加锁**:如果多个线程需要对多个资源加锁,则确保所有线程按照相同的顺序获取锁。 - **使用超时**:在尝试获取锁时使用超时机制,如果超时则放弃尝试,避免无限期地等待。 - **使用工具类**:Java并发库中...

    JAVA锁的膨胀过程-分析-适合Java新手道架构师

    偏向锁是指当一段同步代码一直被同一个线程所访问时,即不存在多个线程的竞争时,那么该线程在后续访问时便会自动获得锁,从而降低获取锁带来的消耗,即提高性能。 轻量级锁的引入是为了在多线程竞争不激烈的前提下...

Global site tag (gtag.js) - Google Analytics