首页 > 其他分享 >死锁-举例

死锁-举例

时间:2024-07-24 15:18:11浏览次数:12  
标签:Thread flag System 死锁 举例 println new

首先回顾我们对死锁的定义,通俗易懂地说就是双方在占有自己手上的资源时,需要对方手上的资源才能继续下去,但是双方又不愿意主动放弃自己手上的资源

用一个生活中通俗易懂的例子就是:对方道歉我就道歉

这个模型用代码实现最简单的框架是这样

public class MustDeadLock implements Runnable{

    public int flag;
    static final Object o1 = new Object();
    static final Object o2 = new Object();

    @Override
    public void run() {
        System.out.println("线程"+Thread.currentThread().getName() + "的flag为" + flag);

        if (flag == 1) {
            synchronized (o1) {
                try {
                    Thread.sleep(500);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                synchronized (o2) {
                    System.out.println("线程1获得了两把锁");
                }
            }
        }

        if (flag == 2) {
            synchronized (o2) {
                try {
                    Thread.sleep(500);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                synchronized (o1) {
                    System.out.println("线程2获得了两把锁");
                }
            }
        }
    }

    public static void main(String[] args) {
        TransferMoney r1 = new TransferMoney();
        TransferMoney r2 = new TransferMoney();
        r1.flag = 1;
        r2.flag = 2;
        Thread t1 = new Thread(r1, "t1");
        Thread t2 = new Thread(r2, "t2");
        t1.start();
        t2.start();
    }
}

然后既然是举例我们需要对这个模型添加一点实际的情景,比如转账

public class TransferMoney implements Runnable {

    static class Account {
        int balance;

        public Account(int balance) {
            this.balance = balance;
        }
    }

    public int flag;
    static Account account1 = new Account(1000);
    static Account account2 = new Account(500);

    @Override
    public void run() {
        // 这里其实是两笔互相转账的操作导致的死锁
        if (flag == 1) transferMoney(account1, account2, 500);
        if (flag == 2) transferMoney(account2, account1, 500);
    }

    private void transferMoney(Account from, Account to, int amount) {
        synchronized (from) {
            System.out.println(Thread.currentThread().getName() + "获取到第一把锁");
            // 确保两把锁分别被不同的线程先拿到,发生死锁
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (to) {
                System.out.println(Thread.currentThread().getName() + "获取到第二把锁");
            }
            if (from.balance - amount < 0) {
                System.out.println("余额不足,转账失败。");
                return;
            }
            from.balance -= amount;
            to.balance += amount;
            System.out.println("成功转账" + amount + "元");
        }
    }

    public static void main(String[] args) throws InterruptedException {
        TransferMoney r1 = new TransferMoney();
        TransferMoney r2 = new TransferMoney();
        r1.flag = 1;
        r2.flag = 2;
        Thread t1 = new Thread(r1, "第一笔转账");
        Thread t2 = new Thread(r2, "第二笔转账");
        t1.start();
        t2.start();
        // 这里的两个join操作是为了保证下面打印余额前两笔转账完成
        t1.join();
        t2.join();
        System.out.println("账户1的余额为:" + account1.balance);
        System.out.println("账户2的余额为:" + account2.balance);
    }
}

死锁检测与避免

# 获取到Java进程的 pid
jps
# 检查线程死锁情况,以及各个线程具体持有的锁情况
jstack 8359

解决思路:

  1. 使用主键或者哈希,确保每次转账尝试获取锁时,尝试获取的都是主键或者哈希值最小的那个锁

引用:银行转账问题(死锁)

标签:Thread,flag,System,死锁,举例,println,new
From: https://www.cnblogs.com/yaocy/p/18320977

相关文章

  • 正则表达式在python爬虫中常用的方法举例
    在爬虫中,正则表达式被广泛用于从网页中提取特定信息。以下是一些常用的正则表达式方法举例,以及它们在爬虫中的典型应用场景:1.提取URLimportreurl_pattern=r'https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+'urls=re.findall(url_pattern,html_content)用于从网页中......
  • 记一个引起MYSQL死锁Deadlock found when trying to get lock; try restarting transac
    一、记一个引起MYSQL死锁Deadlockfoundwhentryingtogetlock;tryrestartingtransaction的例子  今天在尝试MYSQL事务的时候,这种情况总会引起死锁,不知道为什么,我使用的测试MYSQL表的创建SQL如下:CREATETABLE`user`(`id`int(10)unsignedNOTNULLAUTO_INC......
  • 什么是死锁 , 以及产生的原因详细介绍
    死锁一.什么是死锁指的是两个或者两个以上的线程在执行的过程中由于竞争同步锁而产生的一种阻塞现象;如果没有外力的作用,他们将无法继续执行下去,这种情况称之为死锁,通俗的说死锁产生的原因主要是由于线程的相互等待,导致程序无法进行下去二.代码阐述这里我们写......
  • CompletableFuture异步编程—Java8 (附代码举例)
    ......
  • 打破僵局:深度解析数据库死锁的策略与实践(专家篇)
    在多任务操作系统和数据库管理系统中,死锁是一个常见问题,它发生在两个或多个进程/线程因争夺资源而相互等待,导致系统资源无法继续执行。有效地检测和预防死锁对于确保系统稳定性和提高系统性能至关重要。本次探讨不同的死锁检测与预防策略,以及如何在实际应用中实现这些策略......
  • 死锁和产生死锁的条件
    死锁:多个线程同时被阻塞,他们中的一个或者全部都在等待某个资源的释放,由于线程被无限期地阻塞,因此程序不可能正常终止下面展示一些简单死锁代码实例。packagecom.haina.Thread61;publicclassDeadLock{privateObjecto1=newObject();privateObjecto2=......
  • 关于java装饰器模式在ai生成举例不可用的问题
    定义首先描述下定义,然后举例说明。网上定义装饰器模式(DecoratorPattern)是一种结构型设计模式,它允许向对象添加新的功能或职责,同时保持对象类的原始结构。这种模式提供了一种替代继承的机制来扩展功能,因为继承通常是在编译时固定的,而装饰器模式则允许在运行时动态地添加......
  • 死锁案例
    1publicpartialclassForm1:Form2{3publicForm1()4{5InitializeComponent();6}78privatevoidForm1_Load(objectsender,EventArgse)9{1011}1213private......
  • 面试篇-Java-1+锁+AQS+死锁
    文章目录前言一、并发编程中你都用过哪些锁1.1Synchronized【对象锁】1.1.1Synchronized的使用1.1.2你知道Synchronized的原理吗1.1.2.1你知道monitor的结构1.1.3Synchronized的实现原理1.1.3你知道Synchronized锁的升级吗1.1.3.1你知道对象头的内存结构和对......
  • opencv中 在特征点匹配代码举例,以及queryIdx和trainIdx的用法
    一、用法在特征点匹配中,queryIdx和trainIdx是匹配对中的两个索引,用于指示匹配点在不同图像或特征向量中的位置。1.假设我们有两幅图像A和B,并使用特征点提取算法(如SIFT)从它们中提取出特征点和对应的描述子。2.在进行特征点匹配时,我们得到了一个匹配对,其中包含了两个特征点:特征点A......