java避免死锁的常见方法代码解析

死锁

索是一个非常有用的工具,运用场景非常多,因为它使用起来非常简单,而且易于理解。但同时它也会带来一些困扰,那就是可能会引起死锁,一旦产生死锁,就会造成系统功能不可用。让我们先来看一段代码,这段代码会引起死锁,使线程 thread_1 和线程 thread_2 互相等待对方释放锁。

package thread;
public class DeadLockDemo {
	private static String A = "A";
	private static String B = "B";
	public static void main(String args[]) {
		new DeadLockDemo().deadLock();
	}
	private void deadLock() {
		// 线程thread_1
		Thread thread_1 = new Thread(new Runnable() {
			@Override
			   public void run() {
				synchronized (A) {
					System.err.println("--thread_1 lock A----");
					synchronized (B) {
						System.err.println("--thread_1 lock B----");
					}
				}
			}
		}
		);
		// 线程thread_2
		Thread thread_2 = new Thread(new Runnable() {
			@Override
			   public void run() {
				synchronized (B) {
					System.out.println("--thread_2 lock B----");
					synchronized (A) {
						System.out.println("--thread_2 lock A----");
					}
				}
			}
		}
		);
		thread_1.start();
		thread_2.start();
	}
}

这段代码只是演示死锁的场景,在现实中你可能不会写出这样的代码。但是在一些更为复杂的场景中,你可能会遇到这样的问题,比如 thread_1 拿到索之后,因为一些异常情况没有释放索(死循环)。又或者是 thread_1 拿到一个数据库索,释放锁的时候抛出了异常,没释放掉。

一旦出现死锁,业务是可感知的,因为不能继续提供服务了,那么只能通过dump 线程查看到底是哪个线程出现了问题,以下线程信息告诉我们是 DeadLockDemo类的第 35 行和21行引起了死锁。

"Thread-1" prio=6 tid=0x000000000cb13800 nid=0x19ac waiting for monitor entry [0
x000000000d67f000]
 java.lang.Thread.State: BLOCKED (on object monitor)
  at thread.DeadLockDemo$2.run(DeadLockDemo.java:35)
  - waiting to lock <0x00000007d5a9be88> (a java.lang.String)
  - locked <0x00000007d5a9beb8> (a java.lang.String)
  at java.lang.Thread.run(Unknown Source) 

"Thread-0" prio=6 tid=0x000000000cb0e800 nid=0x6bc waiting for monitor entry [0x
000000000d48f000]
 java.lang.Thread.State: BLOCKED (on object monitor)
  at thread.DeadLockDemo$1.run(DeadLockDemo.java:21)
  - waiting to lock <0x00000007d5a9beb8> (a java.lang.String)
  - locked <0x00000007d5a9be88> (a java.lang.String)
  at java.lang.Thread.run(Unknown Source) 

避免死锁的几个常见方法。

避免一个线程同时获取多个锁。

避免一个线程在索内同时占用多个资源,尽量保证每个索只占用一个资源。

尝试使用定时索,使用 lock.tryLock(timeout) 来替代使用内部索机制。

对于数据库索,加锁和解锁必须在一个数据库连接里,否则会出现解锁失败的情况。

referance:

http://www.jb51.net/article/131946.htm

http://www.jb51.net/article/131943.htm

总结

以上就是本文关于java避免死锁的常见方法代码解析的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

您可能感兴趣的文章:

  • Java避免死锁_动力节点Java学院整理
  • Java多线程 线程同步与死锁
  • java 中死锁问题的实例详解
  • Java 线程死锁的问题解决办法
  • Java多线程之死锁的出现和解决方法
  • Java编程之多线程死锁与线程间通信简单实现代码
  • java线程死锁代码示例
(0)

相关推荐

  • Java多线程之死锁的出现和解决方法

    什么是死锁? 死锁是这样一种情形:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放.由于线程被无限期地阻塞,因此程序不能正常运行.形象的说就是:一个宝藏需要两把钥匙来打开,同时间正好来了两个人,他们一人一把钥匙,但是双方都再等着对方能交出钥匙来打开宝藏,谁都没释放自己的那把钥匙.就这样这俩人一直僵持下去,直到开发人员发现这个局面. 导致死锁的根源在于不适当地运用"synchronized"关键词来管理线程对特定对象的访问."synchronized"关

  • Java多线程 线程同步与死锁

     Java多线程 线程同步与死锁 1.线程同步 多线程引发的安全问题 一个非常经典的案例,银行取钱的问题.假如你有一张银行卡,里面有5000块钱,然后你去银行取款2000块钱.正在你取钱的时候,取款机正要从你的5000余额中减去2000的时候,你的老婆正巧也在用银行卡对应的存折取钱,由于取款机还没有把你的2000块钱扣除,银行查到存折里的余额还剩5000块钱,准备减去2000.这时,有趣的事情发生了,你和你的老婆从同一个账户共取走了4000元,但是账户最后还剩下3000元. 使用代码模拟下取款过

  • Java编程之多线程死锁与线程间通信简单实现代码

    死锁定义 死锁是指两个或者多个线程被永久阻塞的一种局面,产生的前提是要有两个或两个以上的线程,并且来操作两个或者多个以上的共同资源:我的理解是用两个线程来举例,现有线程A和B同时操作两个共同资源a和b,A操作a的时候上锁LockA,继续执行的时候,A还需要LockB进行下面的操作,这个时候b资源在被B线程操作,刚好被上了锁LockB,假如此时线程B刚好释放了LockB则没有问题,但没有释放LockB锁的时候,线程A和B形成了对LockB锁资源的争夺,从而造成阻塞,形成死锁:具体其死锁代码如下:

  • Java避免死锁_动力节点Java学院整理

    在有些情况下死锁是可以避免的.本文将展示三种用于避免死锁的技术: 1.加锁顺序 2.加锁时限 3.死锁检测 加锁顺序 当多个线程需要相同的一些锁,但是按照不同的顺序加锁,死锁就很容易发生. 如果能确保所有的线程都是按照相同的顺序获得锁,那么死锁就不会发生.看下面这个例子: Thread 1: lock A lock B Thread 2: wait for A lock C (when A locked) Thread 3: wait for A wait for B wait for C 如果

  • java线程死锁代码示例

    死锁是操作系统层面的一个错误,是进程死锁的简称,最早在 1965 年由 Dijkstra 在研究银行家算法时提出的,它是计算机操作系统乃至整个并发程序设计领域最难处理的问题之一. 事实上,计算机世界有很多事情需要多线程方式去解决,因为这样才能最大程度上利用资源,才能体现出计算的高效.但是,实际上来说,计算机系统中有很多一次只能由一个进程使用的资源的情况,例如打印机,同时只能有一个进程控制它.在多通道程序设计环境中,若干进程往往要共享这类资源,而且一个进程所需要的资源还很有可能不止一个.因此,就会

  • Java 线程死锁的问题解决办法

     Java 线程死锁的问题解决办法 [线程死锁]  原因:两个线程相互等待被对方锁定的资源 代码模拟: public class DeadLock { public static void main(String[] args) { Object obj = new Object(); Object obj1 = new Object(); DeadLockThread1 D1 = new DeadLockThread1(obj, obj1); DeadLockThread2 D2 = new

  • java 中死锁问题的实例详解

    java 中死锁问题的实例详解 先看代码在做解释 public class DeadLock implements Runnable{ String a; String b; boolean flag; public DeadLock(String a,String b,boolean flag){ this.a=a; this.b=b; this.flag=flag; } public void run(){ if(flag){ // while(true){ synchronized(a){

  • java避免死锁的常见方法代码解析

    死锁 索是一个非常有用的工具,运用场景非常多,因为它使用起来非常简单,而且易于理解.但同时它也会带来一些困扰,那就是可能会引起死锁,一旦产生死锁,就会造成系统功能不可用.让我们先来看一段代码,这段代码会引起死锁,使线程 thread_1 和线程 thread_2 互相等待对方释放锁. package thread; public class DeadLockDemo { private static String A = "A"; private static String B = &

  • Java监听器三种实现方法代码解析

    这是没有缩减的写法 //创建一个自定义监听器 private btnlistener btnl = new btnlistener(); //必须在一个btn创建后才添加监听器,即在类里面无法添加但构造函数可以 btn.addActionListener(btnl); //自定义监听器的内容 private class btnlistener implements ActionListener { @Override //实现接口(interface) public void actionPer

  • Java实现一个简单的定时器代码解析

    定时的功能我们在手机上见得比较多,比如定时清理垃圾,闹钟,等等.定时功能在java中主要使用的就是Timer对象,他在内部使用的就是多线程的技术. Time类主要负责完成定时计划任务的功能,就是在指定的时间的开始执行某个任务. Timer类的作用是设置计划任务,而封装任务内容的类是TimerTask类.此类是一个抽象类,继承需要实现一个run方法. 利用java制作定时器比较简单,有现成的接口帮助实现.java中制作定时器使用的是Timer和TimerTask,是util包的.java.util

  • java中幂指数值的运算代码解析

    说到幂指数的运算我们就会用到Math.pow(doublea,doubleb),返回的结果是a的b次方. 在Java中,当我们计算2的n次方时,可以直接用Math.pow来计算.非常方便. 但是,已知一个幂的结果为M和幂的底数a,现在要求幂的指数n.Math中提供的有log(double)方法,但是只能传入一个参数,即M.那么问题来了,如何简单.方便.快捷的达到我们的要求呢?答案如下: n=Math.log(M)/Math.log(a); 这个方法可以满足我们大多数幂指数的计算,但是每次访问的值

  • Eclipse下Javassist正确使用方法代码解析

    这两天看到Hibernate的代理部分,第一反应是底层使用了反射,针对用户实体生成了代理类,后来反应过来了,反射没有任何可以产生新类的能力,也就顺理成章地找到了Javassist(下载地址). 在网上搜索到的大部分教程,都是针对Javassist的API进行一番讲解,但是最后,往往没有一个加载过程,而笔者模仿这些教程进行类的加载时,加载到的结果都是原来的类,并没有产生字节码被修改的内容. 在经过一番探索后,笔者发现,网上的大部分教程中的最后一步,保存字节码,使用的均是writeFile的无参数重

  • JAVA StringBuffer类与StringTokenizer类代码解析

     StringBuffer类提供了一个字符串的可变序列,类似于String类,但它对存储的字符序列可以任意修改,使用起来比String类灵活得多.它常用的构造函数为: StringBuffer() 构造一个空StringBuffer对象,初始容量为16个字符. StringBuffer(Stringstr) 构造一个StringBuffer对象,初始内容为字符串str的拷贝. 对于StringBuffer类,除了String类中常用的像长度.字符串截取.字符串检索的方法可以使用之外,还有两个较为

  • java中的异或问题代码解析

    java的位运算符中有一个叫异或的运算符,用符号(^)表示,其运算规则是:两个操作数的位中,相同则结果为0,不同则结果为1.下面看一个例子: public class TestXOR{ public static void main(String[] args){ int i = 15, j = 2; System.out.println("i ^ j = " + (i ^ j)); } } 运行结果是:i^j=13. 分析上面程序,i=15转成二进制是1111,j=2转成二进制是00

  • java springmvc 注册中央调度器代码解析

    这篇文章主要介绍了java springmvc 注册中央调度器代码解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在WEB-INF下的web.xml中配置 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="htt

  • Java对象转json的方法过程解析

    这篇文章主要介绍了Java对象转json的方法过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1. jsonlib:个人感觉最麻烦的一个需要导入的包也多,代码也相对多一些. 2.Gson:google的 3.FastJson:阿里巴巴的,个人觉得这个比较好,而且据说这个也是性能最好一个. 下面就贴出三种写法的代码,读者可以任选其一去使用.关于demo里面所使用的jar包,可以自行去下载. Jsonlib: package json; i

  • Java线程操作的常见方法【线程名称获取、设置、线程启动判断等】

    本文实例讲述了Java线程操作的常见方法.分享给大家供大家参考,具体如下: 一 线程名称的操作 1 代码 public class GetNameThreadDemo extends Thread { public void run() { for( int i = 0; i < 5; ++i ) { printMsg(); try { Thread.sleep(1000); // 睡眠1秒 } catch( InterruptedException e ) { e.printStackTrac

随机推荐