并发编程9-避免活跃度危害

简介: <div class="markdown_views"><h2 id="死锁">死锁</h2><p>线程等待资源,形成一个环路就会造死锁。 <br>数据库中事务也可能造成死锁,但是事务会自动选择一个杀死,保证另外的运行,线程可没有这么自动</p><h3 id="锁顺序死锁">锁顺序死锁</h3><p>直接上代码 <br>这种死锁,只要保持锁的顺序就不会发生

死锁

线程等待资源,形成一个环路就会造死锁。
数据库中事务也可能造成死锁,但是事务会自动选择一个杀死,保证另外的运行,线程可没有这么自动

锁顺序死锁

直接上代码
这种死锁,只要保持锁的顺序就不会发生

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

    public void left(){
        synchronized (left){
            synchronized (right){
                // dosomething
            }
        }
    }

    public void right(){
        synchronized (right){
            synchronized (left){
                // dosomething
            }
        }
    }
}

动态锁顺序死锁

如下,因为不能保证传入参数的顺序性:

public class TestCallable {
    public void left(Object left, Object right){
        synchronized (left){
            synchronized (right){
                // dosomething
            }
        }
    }
}

如下可以避免死锁:

public class TestCallable {
    public void left(Object left, Object right){
        if(System.identityHashCode(left) > System.identityHashCode(right)){
            synchronized (left){
                synchronized (right){
                    // dosomething
                }
            }
        }else if(System.identityHashCode(right) > System.identityHashCode(left)){
            synchronized (right){
                synchronized (left){
                    // dosomething
                }
            }
        }else{
            synchronized (this){
                // dosomething
            }
        }
    }
}

另外还有可能协作对象间的死锁。这个就防不胜防了。具体问题需要具体分析。不过其实大多数情况下是没有必要给程序加锁的,也就不会出现问题。

资源等待死锁

线程A用到两个数据库连接,持有一个了,不释放,又去拿另外一个,结果池里面没有了,就会造成死锁。
或者是线程A的运行结束依赖于池中B线程,B线程等待A执行结束才会开始执行,就会造成死锁。

避免死锁

定时锁

用显示锁的tryLock来替代内部锁,超时无法获得锁后会抛出异常,重新交回控制权

其他活跃度危险

饥饿

通常是因为CPU的资源不够用了,有一个线程的优先级比较低,总有比他高优先级的在运行,就轮不到他。这种问题现在应该基本不会见到了。

活锁

尽管不会阻塞,但是任然不能执行,因为其会重复相同的操作,永远忙碌状态。
比如一个线程执行失败,然后被加到队尾,然后又执行,又失败。

相关文章
|
6月前
|
存储 缓存 Java
金石原创 |【JVM盲点补漏系列】「并发编程的难题和挑战」深入理解JMM及JVM内存模型知识体系机制(1)
金石原创 |【JVM盲点补漏系列】「并发编程的难题和挑战」深入理解JMM及JVM内存模型知识体系机制(1)
82 1
|
8天前
|
监控 安全 定位技术
《C++新特性:为多线程数据竞争检测与预防保驾护航》
多线程编程是提升软件性能的关键,但数据竞争问题却是一大挑战。C++新特性如增强的原子类型和完善的内存模型,为检测和预防数据竞争提供了有力支持。这些改进不仅提高了程序的可靠性,还提升了开发效率,使多线程编程更加安全高效。
54 19
|
3月前
|
Rust 并行计算 安全
揭秘Rust并发奇技!线程与消息传递背后的秘密,让程序性能飙升的终极奥义!
【8月更文挑战第31天】Rust 以其安全性和高性能著称,其并发模型在现代软件开发中至关重要。通过 `std::thread` 模块,Rust 支持高效的线程管理和数据共享,同时确保内存和线程安全。本文探讨 Rust 的线程与消息传递机制,并通过示例代码展示其应用。例如,使用 `Mutex` 实现线程同步,通过通道(channel)实现线程间安全通信。Rust 的并发模型结合了线程和消息传递的优势,确保了高效且安全的并行执行,适用于高性能和高并发场景。
64 0
|
5月前
|
缓存 并行计算 安全
【并发编程系列一】并发编年史:线程的双刃剑——从优势到风险的全面解析
【并发编程系列一】并发编年史:线程的双刃剑——从优势到风险的全面解析
|
监控 安全 数据安全/隐私保护
在开源代码的时候该如何避免安全风险的发生?
作为开发者来讲,不管是在实际开发中使用开源项目,还是直接投身于开源的贡献中,关于开源相关的内容想必都有自己独到的见解。开源与开发者息息相关,可能有的开发者会觉得不使用开源项目,自己就与开源无关了?这种想法是片面的,因为就算没有在实际开发中使用开源项目,但是在实际开发中肯定会用到一些第三方的插件,那么能保证这些插件没有用到开源的内容么?所以,开源与每一位开发者都有联系。
289 2
在开源代码的时候该如何避免安全风险的发生?
|
安全 Java 调度
吃透Java线程安全问题(上)
吃透Java线程安全问题(上)
|
存储 安全 Java
吃透Java线程安全问题(下)
吃透Java线程安全问题(下)
104 0
|
安全 Java
多线程强化(下)
多线程强化(下)
97 0
多线程强化(下)
|
Oracle Java 关系型数据库
多线程强化(中)
多线程强化(中)
73 0
多线程强化(中)
|
安全 Java 调度
多线程强化(上)
多线程强化(上)
90 0
多线程强化(上)