热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何用Java中的线程解决死锁?

如何用Java中的线程解决死锁?原文:https://www

如何用 Java 中的线程解决死锁?

原文:https://www . geesforgeks . org/如何使用 java 中的线程解决死锁/

如果两个线程永远相互等待,这种类型的无限等待在 java 中被称为死锁。 Synchronized 关键字是死锁情况的唯一原因,因此在使用 Synchronized 关键字时,我们必须特别小心。死锁没有解决技术,但有几种预防技术可用。

实现:死锁发生

例 1:

Java 语言(一种计算机语言,尤用于创建网站)


// Java program to illustrate Deadlock
// where deadlock occurs
// Importing required packages
import java.io.*;
import java.util.*;
// Class 1
// Helper class
class A {
    // Method 1 of this class
    // Synchronized method
    public synchronized void last()
    {
        // Print and display statement
        System.out.println("Inside A, last() method");
    }
    // Method 2 of this class
    // Synchronized method
    public synchronized void d1(B b)
    {
        System.out.println(
            "Thread1 start execution of d1() method");
        // Try block to check for exceptions
        try {
            // Putting the current thread to sleep for
            // specific time using slep() method
            Thread.sleep(2000);
        }
        // Catch block to handle the exceptions
        catch (InterruptedException e) {
            // Display the exception on the console
            System.out.println(e);
        }
        // Display statement
        System.out.println(
            "Thread trying to call B's last() method");
        // Calling the method 1 of this class as created
        // above
        b.last();
    }
}
// Class 2
// Helper class B
class B {
    // Method 1 of this class
    public synchronized void last()
    {
        // Display statement only
        System.out.println("Inside B, last() method");
    }
    // Method 2 of this class
    // Synchronized the method d2
    public synchronized void d2(A a)
    {
        // Display message only
        System.out.println(
            "Thread2 start execution of d2() method");
        // Try block to check for exceptions
        try {
            // Putting the current thread to sleep for
            // certain time using sleep() method
            Thread.sleep(2000);
            // Catch block to handle the exceptions
        }
        catch (InterruptedException e) {
            // Display the exception on the console
            System.out.println(e);
        }
        // Display message only
        System.out.println(
            "Thread2  trying to call A's last method");
        // Again calling the last() method inside this class
        a.last();
    }
}
// Class 3
// Main class
// Deadlock class which is extending Thread class
class GFG extends Thread {
    // Creating object of type class A
    A a = new A();
    // Creating object of type class B
    B b = new B();
    // Method 1
    public void m1()
    {
        // Starting the thread
        this.start();
        // Calling d1 method of class A
        a.d1(b);
    }
    // Method 2
    // run() method for the thread
    public void run()
    {
        // Calling d2 method of class B
        b.d2(a);
    }
    // Method 3
    // Main driver method
    public static void main(String[] args)
    {
        // Creating object of this class
        GFG deadlock = new GFG();
        // Calling m1 method
        deadlock.m1();
    }
}

输出:

输出解释:

这里光标永远显示,因为线程进入死锁状态。在上面的程序中,如果我们删除了至少一个同步关键字,那么程序就不会进入死锁状态。因此,synchronized 关键字是死锁情况的主要原因之一。因此,在使用同步关键字时,我们必须特别小心。

我们可以通过以下方式避免死锁情况:


  • 使用 Thread.join()方法:如果两个线程无限期地等待对方使用 thread join 完成,我们会得到死锁。那么我们的线程就要等待另一个线程完成,最好总是使用 Thread.join()方法,最长的时间你要等待线程完成。

  • 使用锁排序:我们必须始终为每个锁分配一个数值,在获取具有较高数值的锁之前,我们必须获取具有较低数值的锁。

  • 避免不必要的锁:我们应该只对那些需要锁的成员使用锁,不必要的使用锁会导致死锁的情况。并且建议使用无锁的数据结构,如果是可以让你的代码免锁。例如,不要使用同步数组列表,而是使用 ConcurrentLinkedQueue。

示例 2: 防止死锁

Java 语言(一种计算机语言,尤用于创建网站)


// Java program to illustrate Deadlock
// where deadlock is pevented from occuring
// Importing required packages
import java.io.*;
import java.util.*;
// Class 1
// Helper class
class A {
    // Method 1 of this class
    // Synchronized method
    public synchronized void last()
    {
        // Print and display statement
        System.out.println("Inside A, last() method");
    }
    // Method 2 of this class
    // Synchronized method
    public synchronized void d1(B b)
    {
        System.out.println(
            "Thread1 start execution of d1() method");
        // Try block to check for exceptions
        try {
            // Putting the current thread to sleep for
            // specific time using slep() method
            Thread.sleep(2000);
        }
        // Catch block to handle the exceptions
        catch (InterruptedException e) {
            // Display the exception on the console
            System.out.println(e);
        }
        // Display statement
        System.out.println(
            "Thread trying to call B's last() method");
        // Calling the method 1 of this class as created
        // above
        b.last();
    }
}
// Class 2
// Helper class B
class B {
    // Method 1 of this class
    public void last()
    {
        // Display statement only
        System.out.println("Inside B, last() method");
    }
    // Method 2 of this class
    // Non-synchronized the method d2
    public void d2(A a)
    {
        // Display message only
        System.out.println(
            "Thread2 start execution of d2() method");
        // Try block to check for exceptions
        try {
            // Putting the current thread to sleep for
            // certain time using sleep() method
            Thread.sleep(2000);
            // Catch block to handle the exceptions
        }
        catch (InterruptedException e) {
            // Display the exception on the console
            System.out.println(e);
        }
        // Display message only
        System.out.println(
            "Thread2  trying to call A's last method");
        // Again calling the last() method inside this class
        a.last();
    }
}
// Class 3
// Main class
// Deadlock class which is extending Thread class
class GFG extends Thread {
    // Creating object of type class A
    A a = new A();
    // Creating object of type class B
    B b = new B();
    // Method 1
    public void m1()
    {
        // Starting the thread
        this.start();
        // Calling d1 method of class A
        a.d1(b);
    }
    // Method 2
    // run() method for the thread
    public void run()
    {
        // Calling d2 method of class B
        b.d2(a);
    }
    // Method 3
    // Main driver method
    public static void main(String[] args)
    {
        // Creating object of this class
        GFG deadlock = new GFG();
        // Calling m1 method
        deadlock.m1();
    }
}

输出:


推荐阅读
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • 在springmvc框架中,前台ajax调用方法,对图片批量下载,如何弹出提示保存位置选框?Controller方法 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • 关键词:Golang, Cookie, 跟踪位置, net/http/cookiejar, package main, golang.org/x/net/publicsuffix, io/ioutil, log, net/http, net/http/cookiejar ... [详细]
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
  • switch语句的一些用法及注意事项
    本文介绍了使用switch语句时的一些用法和注意事项,包括如何实现"fall through"、default语句的作用、在case语句中定义变量时可能出现的问题以及解决方法。同时也提到了C#严格控制switch分支不允许贯穿的规定。通过本文的介绍,读者可以更好地理解和使用switch语句。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
author-avatar
雅芳07866
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有