b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

JAVA多线程死锁问题

电脑杂谈  发布时间:2019-06-22 05:16:18  来源:网络整理

java多线程死锁_线程死锁_java线程死锁

1. Java中导致死锁的原因

Java中死锁最简单的情况是,一个线程T1持有锁L1并且申请获得锁L2,而另一个线程T2持有锁L2并且申请获得锁L1,因为默认的锁申请操作都是阻塞的,所以线程T1和T2永远被阻塞了。导致了死锁。这是最容易理解也是最简单的死锁的形式。但是实际环境中的死锁往往比这个复杂的多。可能会有多个线程形成了一个死锁的环路,比如:线程T1持有锁L1并且申请获得锁L2,而线程T2持有锁L2并且申请获得锁L3,而线程T3持有锁L3并且申请获得锁L1java多线程死锁,这样导致了一个锁依赖的环路:T1依赖T2的锁L2,T2依赖T3的锁L3,而T3依赖T1的锁L1。从而导致了死锁。

从这两个例子,我们可以得出结论,产生死锁可能性的最根本原因是:线程在获得一个锁L1的情况下再去申请另外一个锁L2,也就是锁L1想要包含了锁L2,也就是说在获得了锁L1,并且没有释放锁L1的情况下,又去申请获得锁L2,这个是产生死锁的最根本原因。另一个原因是默认的锁申请操作是阻塞的。

2. Java中如何避免死锁

既然我们知道了产生死锁可能性的原因,那么就可以在编码时进行规避。Java是面向对象的编程语言,程序的最小单元是对象,对象封装了数据和操作,所以Java中的锁一般也是以对象为单位的,对象的内置锁保护对象中的数据的并发访问。所以如果我们能够避免在对象的同步方法中调用其它对象的同步方法,那么就可以避免死锁产生的可能性。如下所示的代码,就存在死锁的可能性:

public class ClassB {

private String address;

// ...

public synchronized void method1(){

// do something

}

// ... ...

}

public class ClassA {

java线程死锁_线程死锁_java多线程死锁

private int id;

private String name;

private ClassB b;

// ...

public synchronized void m1(){

// do something

b.method1();

}

// ... ...

}

上面的ClassA.m1()方法,在对象的同步方法中又调用了ClassB的同步方法method1(),所以存在死锁发生的可能性。我们可以修改如下,避免死锁:

public class ClassA {

private int id;

private String name;

线程死锁_java线程死锁_java多线程死锁

private ClassB b;

// ...

public void m2(){

synchronized(this){

// do something

}

b.method1();

}

// ... ...

}

wait是object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyall)后本线程才进入对象锁定池准备获得对象锁进入运行状态。 wait是object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyall)后本线程才进入对象锁定池准备获得对象锁进入运行状态。需要注意的是在使用互斥锁的过程中很有可能会出现死锁:两个线程试图同时占用两个资源,并按不同的次序锁定相应的互斥锁,例如两个线程都需要锁定互斥锁1和互斥锁2,a线程先锁定互斥锁1,b线程先锁定互斥锁2,这时就出现了死锁。

对于支付机构自主或委托合作机构以面对面方式核实身份的个人客户,或以非面对面方式通过至少五个合法安全的外部渠道进行身份基本信息多重交叉验证的个人客户,支付机构可以为其开立Ⅲ类支付账户,账户余额可以用于消费、转账以及购买投资理财等金融类产品,其所有支付账户的余额付款交易年累计不超过20 万元(不包括支付账户向客户本人同名银行账户转账)。此外,《办法》第三章第十一条(三)中指出,对于支付机构自主或委托合作机构以面对面方式核实身份的个人客户,或以非面对面方式通过至少五个合法安全的外部渠道进行身份基本信息多重交叉验证的个人客户,支付机构可以为其开立Ⅲ类支付账户,账户余额可以用于消费、转账以及购买投资理财等金融类产品,其所有支付账户的余额付款交易年累计不超过20 万元(不包括支付账户向客户本人同名银行账户转账)。业务受理:办理转账服务,增设理财账户,申请本票,转存定期存款,更改电话银行密码及atm取现密码,申请支票簿和账户对账单,及其他账户服务。

public class Account {

private int id; // 主键

线程死锁_java线程死锁_java多线程死锁

private String name;

private double balance;

public void transfer(Account from, Account to, double money){

if(from.getId() > to.getId()){

synchronized(from){

synchronized(to){

// transfer

}

}

}else{

synchronized(to){

synchronized(from){

// transfer

}

java多线程死锁_java线程死锁_线程死锁

}

}

}

public int getId() {

return id;

}

}

使用两个线程来争夺一把锁,当某个线程获得锁后,sleep6秒,每个线程都只尝试5秒去获得锁。事实上,有些互斥量在获得锁时,如果当前锁不能获得,线程并不马上睡眠,而是忙等一段时间,看能否获得(而自旋锁是一直忙等),若超过一定的时间,线程才进入睡眠状态。srw锁可以使用上面两种模式中任意一种模式获得,通常读线程使用共享模式获得srw锁,写线程通常使用独占模式获得srw锁。

如果释放互斥量锁时有多个线程阻塞,所有阻塞在该互斥量的线程都会变成可运行状态,其中第一个变成可运行状态的线程获得互斥量的锁,其他线程会再次阻塞。对互斥量加锁后,其他线程试图对互斥量加锁时都会被阻塞直到互斥量的锁释放(注意如果线程试图对同一个互斥量加锁两次,那么它自身就会陷入阻塞,即死锁状态。这里篮子是一个互斥区,每次放鸡蛋是互斥的,每次取鸡蛋也是互斥的,a线程放鸡蛋,如果这时b线程要取鸡蛋,由于a没有释放锁,b线程处于等待状态,进入阻塞队列,放鸡蛋之后,要通知b线程取鸡蛋,b线程进入就绪队列,反过来,b线程取鸡蛋,如果a线程要放 鸡蛋,由于b线程没有释放锁,a线程处于等待状态java多线程死锁,进入阻塞队列,取鸡蛋之后,要通知a线程放鸡蛋,a线程进入就绪队列。

公平锁是指多个线程在等待同一个锁的时候,必须按照申请锁的时间顺序依次获得锁。同步嵌套是产生死锁的常见情景,从上面的代码中我们可以看出,当t1线程拿到锁a后,睡眠2秒,此时线程t2刚好拿到了b锁,接着要获取a锁,但是此时a锁正好被t1线程持有,因此只能等待t1线程释放锁a,但遗憾的是在t1线程内又要求获取到b锁,而b锁此时又被t2线程持有,到此结果就是t1线程拿到了锁a同时在等待t2线程释放锁b,而t2线程获取到了锁b也同时在等待t1线程释放锁a,彼此等待也就造成了线程死锁问题。(3)线程2的run)(方法中同步代码块先获取lock2的对象锁,接着获取lock1的对象锁,当然这时lock1的对象锁已经被线程1锁持有,线程2肯定是要等待线程1释放lock1的对象锁的。

此时如果T3申请锁L1失败,那么T3释放锁L3,并进行睡眠,那么T2就可以获得L3了,然后T2执行完之后释放L2, L3,所以T1也可以获得L2了执行完然后释放锁L1, L2,然后T3睡眠醒来,也可以获得L1, L3了。打破了死锁的闭环。

这些情况,都还是比较好处理的,因为它们都是相关的,我们很容易意识到这里有发生死锁的可能性,从而可以加以防备。很多情况的场景都不会很明显的让我们察觉到会存在发生死锁的可能性。所以我们还是要注意:

一旦我们在一个同步方法中,或者说在一个锁的保护的范围中,调用了其它对象的方法时,就要十而分的小心:

1)如果其它对象的这个方法会消耗比较长的时间,那么就会导致锁被我们持有了很长的时间;

2)如果其它对象的这个方法是一个同步方法,那么就要注意避免发生死锁的可能性了;

当任意一个线程进入到一个对象的任意一个同步方法时,这个对象的所有同步方法都被锁定了,在此期间,其他任何线程都不能访问这个对象的任意一个同步方法,直到这个线程执行完它所调用的同步方法并从中退出,从而导致它释放了该对象的同步锁之后。 一个lock对象上可以绑定多个condition对象,这样实现了本方线程只唤醒对方线程,而jdk1.5之前,一个同步只能有一个锁,不同的同步只能用锁来区分,且锁嵌套时容易死锁。c:静态同步方法(锁对象时当前类的字节码文件对象)。


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-107568-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      • 崔公佐客
        崔公佐客

        去不了只能舔屏了

        • 胡明阳
          胡明阳

          用铁的事实证明了制定建造出众多鬼城的决策是多么的高瞻远瞩

      热点图片
      拼命载入中...