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中的锁对象。Java提供了多种类型的锁,其中最基础的是`synchronized`关键字,它...
Java双重检查加锁单例模式是一种常用的单例模式实现方法,但是在多线程环境下,它存在一些问题。在这篇文章中,我们将探讨Java双重检查加锁单例模式的详解,包括它的优点和缺点,以及如何正确地使用它。 Java双重...
2. **修饰静态方法**:等同于对类的Class对象加锁,所有实例共享同一把锁。 3. **修饰代码块**:指定要锁定的对象,只对代码块进行锁定,提高了锁的粒度,降低了锁冲突的可能性。 在实际编程中,合理使用`...
Java 提供了 synchronized 关键字来对对象加锁。加锁的对象将被锁定,其他线程必须等待当前线程释放锁后才能访问该对象。有三种方式使用 synchronized: * 锁住方法:public synchronized void print() {...;} * 锁...
综上所述,"多线程文件加锁自动定时查询mysql统计数据"这个任务涵盖了并发编程、文件系统操作、数据库管理和数据分析等多个IT领域的关键知识点,实现这样的系统需要综合运用多种技术和工具。在实际开发过程中,需要...
Java多线程编程是Java开发中的重要组成部分,它允许程序同时执行多个任务,极大地提高了程序的效率和响应性。在Java中,多线程主要通过继承Thread类或实现Runnable接口来实现。本教程《Java多线程编程核心技术》将...
Java多线程与锁是Java并发编程中的核心概念,它们...综上所述,Java多线程和锁是解决并发问题的关键,它们涉及线程创建、管理、同步和通信等多个方面。通过深入学习和实践,开发者能够构建出更加稳定、高效的并发程序。
`synchronized`是Java内置的原生锁,它提供了对方法或代码块的锁定,使得在任何时刻只有一个线程能够执行特定的代码。synchronized有以下特性: 1. **互斥性**:当一个线程进入一个由synchronized修饰的方法或代码...
Java中的`synchronized`关键字是用于...无论是同步方法还是同步代码块,其核心都是通过对特定对象加锁,实现线程间的同步,防止数据竞争。正确理解和使用`synchronized`可以帮助我们编写出更加安全、可靠的多线程程序。
Java多线程与同步是Java编程中的核心概念,它们在构建高效、响应迅速的应用程序时起着至关重要的作用。在Java中,多线程允许同时执行多个代码段,从而提高程序的执行效率,特别是在处理I/O密集型或计算密集型任务时...
`Thread` 类实例仅仅是Java中的一个对象,具有变量和方法,并存在于堆上。每个Java线程都有自己的调用栈,即使是未显式创建的线程也不例外。主线程是程序开始运行的地方,即从 `main()` 方法启动。一旦创建了一个新...
- **修饰代码块**:指定加锁对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁。 ##### 3.2 volatile关键字 `volatile`关键字确保变量的可见性和禁止指令重排序。当一个共享变量被volatile修饰时,它会...
对临界资源Critical_Resources类进行操作方法声明为synchronized,当方法被该关键字声明后,也就意味着,如果这个资源类被加锁,只有一个对象得到这个类的锁的时候该对象才能对这个类进行操作。这里设置了一个管理...
在char01包里放置Java多线程基本知识的代码。内容如下使用多线程如何获取多线程的一些信息本课程停止课程在线暂停流程有些词语在char02包里放置了Java对变量和对象所携带的知识的代码。内容如下对于方法的同步处理...
- **并发**:指一个系统内多个进程或线程交替执行的过程,每个任务都可能被执行一小段时间,然后让位给其他任务,使得多个任务看起来同时运行。 - **并行**:指多个任务在同一时刻执行,通常需要多个处理器或者多核...
fail-fast 是 Java 集合框架中的一个机制,当多个线程对同一个集合的内容进行操作时,就可能会产生 fail-fast 事件。例如:当某一个线程 A 通过 iterator 去遍历某集合的过程中,若该集合的内容被其他线程所改变了;...
多线程编程是Java技术的重要方面,它允许同时执行多个任务,提高程序的执行效率。然而,在多线程环境下,如果不正确使用同步机制,就容易产生死锁、资源竞争等问题。因此,了解在什么情况下需要加锁、如何正确加锁...
例如,Account类中的deposit()和withdraw()方法都使用了synchronized关键字,以确保对amount变量的访问是同步的,防止多个线程同时对同一个Account对象执行存款和取款操作时发生冲突。 接下来,我们看到了Account类...
- **按顺序加锁**:如果多个线程需要对多个资源加锁,则确保所有线程按照相同的顺序获取锁。 - **使用超时**:在尝试获取锁时使用超时机制,如果超时则放弃尝试,避免无限期地等待。 - **使用工具类**:Java并发库中...