当前位置: 首页 > news >正文

红色 网站企业培训课程设置

红色 网站,企业培训课程设置,做旅游网站的引言,做三级锅炉证模拟考试的网站死锁 1、介绍 在 Java 中使用多线程,就会有可能导致死锁问题。死锁会让程序一直卡住,程序不再往下执行。只能通过中止并重启的方式来让程序重新执行。要尽可能避免死锁的情况发生 2、造成死锁的原因 互斥条件: 同一资源同时只能由一个线程读…

死锁

1、介绍

在 Java 中使用多线程,就会有可能导致死锁问题。死锁会让程序一直卡住,程序不再往下执行。只能通过中止并重启的方式来让程序重新执行。要尽可能避免死锁的情况发生

2、造成死锁的原因

互斥条件:
同一资源同时只能由一个线程读取

不可抢占条件:
不能强行剥夺线程占有的资源

请求和保持条件:
请求其他资源的同时对自己手中的资源保持不放

循环等待条件:
在相互等待资源的过程中,形成一个闭环

预防死锁:
只需要破坏其中一个条件即可,比如使用定时锁、尽量让线程用相同的加锁顺序,加锁超时或自动释放,死锁检测算法等等

3、避免死锁的方法

  • 固定加锁的顺序(针对锁顺序死锁)
  • 开放调用(针对对象之间协作造成的死锁)
  • 使用定时锁–>tryLock();如果等待获取锁时间超时,则抛出异常而不是一直等待

二、顺序死锁

例子

public class ThreadTest6 {public static void main(String[] args) {Demo demo = new Demo();new Thread(demo,"1").start();new Thread(demo,"2").start();new Thread(demo,"3").start();new Thread(demo,"4").start();}}class Demo implements Runnable{Account a = new Account("A",1000);Account b = new Account("B",1000);@Overridepublic void run() {transferMoney(a,b,100);transferMoney(b,a,100);}public void  transferMoney(Account fromAccount, Account toAccount,double money) {synchronized (fromAccount) {System.out.println("线程" + Thread.currentThread().getName() + "得到锁" + fromAccount.getName());synchronized (toAccount) {System.out.println("线程" + Thread.currentThread().getName() + "得到锁" + toAccount.getName());if(fromAccount.getMoney() < money) {System.out.println("余额不足");} else {fromAccount.setMoney(fromAccount.getMoney()-money);toAccount.setMoney(toAccount.getMoney() + money);System.out.println("转账后:" + fromAccount.getName() + "有:" + fromAccount.getMoney());System.out.println("转账后:" + toAccount.getName() + "有:" + toAccount.getMoney());}}}}
}
class Account{public Account(String name, double money) {this.name = name;this.money = money;}private String name;private double money;public String getName() {return name;}public void setName(String name) {this.name = name;}public double getMoney() {return money;}public void setMoney(double money) {this.money = money;}}

代码有可能会发生死锁:如果两个线程同时调用 transferMoney(),线程A 从 X账户 向 Y账户 转账,线程B 从 账户Y 向 账户X 转账,那么就会发生死锁

避免死锁

上面 transferMoney() 发生死锁的原因是因为加锁顺序不一致而出现的;如果所有线程以固定的顺序来获得锁,那么程序中就不会出现锁顺序死锁问题

上面的例子改造:

public class InduceLockOrder {// 额外的锁、避免两个对象hash值相等的情况(即使很少)private static final Object tieLock = new Object();public void transferMoney(final Account fromAcct,  final Account toAcct, final DollarAmount amount)  throws InsufficientFundsException {class Helper {public void transfer()  throws InsufficientFundsException {if (fromAcct.getBalance().compareTo(amount) < 0)throw new InsufficientFundsException();else {fromAcct.debit(amount);toAcct.credit(amount);}}}// 得到锁的hash值int fromHash = System.identityHashCode(fromAcct);int toHash = System.identityHashCode(toAcct);// 根据hash值来上锁if (fromHash < toHash) {synchronized (fromAcct) {synchronized (toAcct) {new Helper().transfer();}}} else if (fromHash > toHash) {// 根据hash值来上锁synchronized (toAcct) {synchronized (fromAcct) {new Helper().transfer();}}} else {// 额外的锁、避免两个对象hash值相等的情况(即使很少)synchronized (tieLock) {synchronized (fromAcct) {synchronized (toAcct) {new Helper().transfer();}}}}}
}

得到对应的 hash值 来固定加锁的顺序,这样就不会发生死锁的问题

三、协作对象之间发生死锁

发生条件

A对象 的一个同步方法调用了 B对象 的同步方法。且有,B对象 的一个同步方法调用了 A对象 的一个同步方法。则可能发生:A线程 得到了 A对象 锁,B对象 同时得到了 B对象 锁,都不会释放,且都无法继续执行,就发生了死锁

开放调用避免死锁

在协作对象之间发生死锁中,主要是因为在调用某个方法时就需要持有锁,并且在方法内部也调用了其他带锁的方法;如果在调用某个方法时不需要持有锁,那么这种调用被称为开放调用;可以在方法中使用同步代码块来实现同步,调用另一对象的同步方法不放在同步代码块中,就解决了问题

四、定时锁避免死锁

tryLock 方法

使用显式 Lock 锁,在获取锁时使用 tryLock() 方法。当等待超过时限的时候,tryLock() 不会一直等待,而是返回错误信息

tryLock 是防止自锁的一个重要方式

tryLock() 方法是有返回值的,它表示用来尝试获取锁,如果获取成功,则返回true,如果获取失败(即锁已被其他线程获取),则返回false,这个方法无论如何都会立即返回。在拿不到锁时不会一直在那等待

例子

public class tryLock {public static void main(String[] args) {System.out.println("开始");final Lock lock = new ReentrantLock();new Thread() {@Overridepublic void run() {String tName = Thread.currentThread().getName();if (lock.tryLock()) {System.out.println(tName + "获取到锁!");} else {System.out.println(tName + "获取不到锁!");return;}try {for (int i = 0; i < 5; i++) {System.out.println(tName + ":" + i);}Thread.sleep(5000);} catch (Exception e) {System.out.println(tName + "出错了!!!");} finally {System.out.println(tName + "释放锁!!");lock.unlock();}}}.start();new Thread() {@Overridepublic void run() {String tName = Thread.currentThread().getName();if (lock.tryLock()) {System.out.println(tName + "获取到锁!");} else {System.out.println(tName + "获取不到锁!");return;}try {for (int i = 0; i < 5; i++) {System.out.println(tName + ":" + i);}} catch (Exception e) {System.out.println(tName + "出错了!!!");} finally {System.out.println(tName + "释放锁!!");lock.unlock();}}}.start();System.out.println("结束");}
}

五、总结

发生死锁的原因主要由于:

线程之间交错执行
解决: 以固定的顺序加锁

执行某方法时就需要持有锁,且不释放
解决: 缩减同步代码块范围,最好仅操作共享变量时才加锁

永久等待
**解决:**n使用 tryLock() 定时锁,超过时限则返回错误信息

http://www.yidumall.com/news/97309.html

相关文章:

  • 我要网站建设百度游戏排行榜风云榜
  • wordpress restapi什么是优化师
  • 易语言如何做验证系统官方网站排名软件下载
  • 关于网站建设的职位营销计划
  • 如何鉴定网站做的好坏网络营销软件大全
  • 专业做数据的网站有哪些方面seo北京网站推广
  • 网站 建设后台女生做sem专员的工作难吗
  • 深圳网站建设合同搜索引擎分哪三类
  • 高端网站建设专业seo关键词大搜
  • 湛江人做寄生虫网站域名免费注册0元注册
  • 漳浦县网站建设哈尔滨优化网站方法
  • 怎么免费做公司网页广州营销seo
  • 汕头企业做网站东莞外贸推广公司
  • 建网站资料企点客服
  • 政和网站建设wzjseo网络优化工程师前景
  • 网站建设开发技术类型百度ai助手入口
  • 旅游网站建设的市场分析windows优化大师怎么下载
  • 明星 卡片网站该怎么做营销推广是什么意思
  • 京东商城网站建设教程佛山快速排名seo
  • 网站建设与管理知识点怎么给网站做优化
  • 网站推广途径方法百度影响力排名顺序
  • WordPress导出单页百度seo优化教程免费
  • 做微商有什么好的货源网站b站推广网站2024mmm
  • 网站开发使用架构软文范例100例
  • 劳务公司网站建设方案谷歌优化排名公司
  • 网站开发技术人员怎么接单互联网销售是什么意思
  • 网站建设步骤的论文友链网
  • 网站界面设计需要首先做市场研究上海站优云网络科技有限公司
  • 网站运行时错误如何做免费收录链接网
  • 网站建设讠金手指科杰做什么推广最赚钱