java并发编程(3)避免活跃性危险

活跃性危险

一、死锁

  发生:每个人都不愿意放弃自己的锁,确想要别人的锁,这就会导致死锁

   1.锁顺序死锁:如果每个线程以固定的顺序获取锁,那么至少在程序中不会出现锁顺序导致的死锁;

    因为顺序固定如:所有线程:A-B-C 则无问题,如果一个A-B B-A则会发生死锁

  例子1:简单死锁

public class LeftRightDeadlock {
    private final Object left = new Object();
    private final Object right = new Object();

    public void leftRight() {
        synchronized (left) {       //锁住left
            synchronized (right) {  //锁住right
                doSomething();
            }
        }
    }
    //如果一个线程进入上面方法锁住 left,另一个线程进入下面方法锁住right,则会产生互相等待 而死锁
    public void rightLeft() {
        synchronized (right) {      //锁住right
            synchronized (left) {   //锁住left
                doSomethingElse();
            }
        }
    }

    void doSomething() {
    }

    void doSomethingElse() {
    }
}

  例子2:转账死锁

public static void transferMoney(Account fromAccount,Account toAccount,DollarAmount amount)
            throws InsufficientFundsException {
        //转账 a-b 和 b-a ,如果同时发生,则有可能发生死锁;这种取决于参数的传入;并不是能够完全的判断得到
        synchronized (fromAccount) {
            synchronized (toAccount) {
                if (fromAccount.getBalance().compareTo(amount) < 0)
                    throw new InsufficientFundsException();
                else {
                    fromAccount.debit(amount);
                    toAccount.credit(amount);
                }
            }
        }
    }

  

  2.资源死锁

    同时获取资源,而资源却相互被锁住,就会产生死锁;

      如:一个应用有两个数据库,刚好两个线程进入两个连接池,两个连接池都满了,则需要相互等待对方释放连接

      线程饥饿死锁:表现为线程池不够,线程池内的线程相互等待(A提交B到单线程池,右提交C到单线程池,但是B要等待C完成才能执行)

  3.活锁

    不会阻塞线程,但是也不能继续执行

    类似于程序不断尝试不断失败,永远无法跳出来

时间: 2024-11-03 22:43:44

java并发编程(3)避免活跃性危险的相关文章

《Java并发编程实战》第十章 避免活跃性危险 读书笔记

一.死锁 所谓死锁: 是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去. 百科百科 当两个以上的运算单元,双方都在等待对方停止运行,以取得系统资源,但是没有一方提前退出时,这种状况,就称为死锁.维基百科 1. 顺序死锁 最少有两个锁,一个线程获取到A锁需要获取B锁才能进行操作,而另外一个线程获取到了B锁,需要获取A锁才能执行操作,这种情况下容易出现顺序死锁. public class LeftRightDeadlock { priva

java并发编程实战学习笔记之第三部分:活跃性、性能与测试

第十章 避免活跃性危险 锁顺序死锁:定义锁的顺序,可以通过某种方法决定每个锁的顺序,比如hashcode或者序列号之类的 在锁的调用顺序不是很明显的情况下,在持有锁的情况下调用其他外部方法一定要注意,可以通过开放调用,避免发生死锁的危险,即使用同步代码块保护仅仅保护那些共享变量即可,但这种降低锁粒度的方法可能会使得原本大的代码块失去原子性,解决办法为:将服务的状态改为关闭之前一直持有锁,状态改变之后,其他线程也就能够看到关闭信息从而不会再次执行关闭操作... 死锁的诊断与避免:    通过try

Java 并发编程之图形界面应用程序及死锁问题

不知道为什么这本书还要讲一个界面应用程序,Java的界面做的很糟糕,效率低下,而且界面是java的弱项,可能是因为这里边是有一些并发编程的知识吧. 为什么GUI是单线程的 无论是Swing还是AWT都是单线程的.但它不仅限于在java中,在Qt,NexiStep,macOs CoCoa X windows以及其它环境中的GUI框架都是单线程的,许多人都曾经尝试编写多线程的GUI框架,但最终都由于竞态条件和死锁导致的稳定性问题而又重新回到单线程的事件队列模型:采用一个专门的线程从队列中抽取事件,并

java并发编程实战笔记

1.复合操作 若一个类里有多个属性状态,对每个属性使用atomic类修饰,并且一个属性更新,要在同一原子操作内更新其他所有属性,这样才是线程安全类.需要整体类的状态操作是原子的. 要保持状态的一致性,就需要在单个原子操作中更新所有相关的状态变量. 判断同步代码块的合理大小,要权衡安全性.简单性和性能. 当执行时间较长的计算或可能无法快速完成的操作(如网络IO.控制台IO)一定不要持有锁. 2.对象的共享 1)可见性 为了确保所有线程都能看到共享变量的最新值,所有执行读操作或写操作的线程都必须在同

《Java并发编程实战》要点笔记及java.util.concurrent 的结构介绍

买了<java并发编程实战>这本书,看了好几遍都不是很懂,这个还是要在实战中找取其中的要点的,后面看到一篇文章笔记做的很不错分享给大家!! 原文地址:http://blog.csdn.net/cdl2008sky/article/details/26377433 Subsections  1.线程安全(Thread safety) 2.锁(lock) 3.共享对象 4.对象组合 5.基础构建模块 6.任务执行 7.取消和关闭 8.线程池的使用 9.性能与可伸缩性 10.并发程序的测试 11.显

《Java并发编程实战》读书笔记

Subsections 线程安全(Thread safety) 锁(lock) 共享对象 对象组合 基础构建模块 任务执行 取消和关闭 线程池的使用 性能与可伸缩性 并发程序的测试 显示锁 原子变量和非阻塞同步机制 一.线程安全(Thread safety) 无论何时,只要多于一个线程访问给定的状态变量.而且其中某个线程会写入该变量,此时必须使用同步来协助线程对该变量的访问. 线程安全是指多个线程在访问一个类时,如果不需要额外的同步,这个类的行为仍然是正确的. 线程安全的实例: (1).一个无状

《Java并发编程实战》/童云兰译【PDF】下载

<Java并发编程实战>/童云兰译[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230062521 内容简介 本书深入浅出地介绍了Java线程和并发,是一本完美的Java并发参考手册.书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险.构造线程安全的类及验证线程安全的规则,如何将小的线程安全类组合成更大的线程安全类,如何利用线程来提高并发应用程序的吞吐量,如何识别可并行执行的任务,如何提高单线程子

Java并发编程实战(中文版)pdf

下载地址:网盘下载 内容简介  · · · · · · 本书深入浅出地介绍了Java线程和并发,是一本完美的Java并发参考手册.书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险.构造线程安全的类及验证线程安全的规则,如何将小的线程安全类组合成更大的线程安全类,如何利用线程来提高并发应用程序的吞吐量,如何识别可并行执行的任务,如何提高单线程子系统的响应性,如何确保并发程序执行预期任务,如何提高并发代码的性能和可伸缩性等内容,最后介绍了一些高级主题,

java并发编程-学习

disruptor:https://www.cnblogs.com/sigm/p/6251910.html 自旋锁等:http://www.cnblogs.com/lzh-blogs/p/7477157.html 1.竞态条件:多个线程共享相同的内存地址空间,并且并发执行下发生访问或修改其他线程正在使用的变量,而导致结果不一致. 2.活跃性:某件正确的事情最终发生,但不够好,因此需要解决性能问题 3.在多线程中,当线程调度器临时挂起活跃线程并转而运行另外一个线程时,就会产生频繁的上下文切换(Co