线程死锁

当需要执行一些原子性操作的代码时,某个代码块或者方法就需要用到线程锁,但是在代码块或者方法中调用其他原子性方法时,就会出现当前代码块或者方法没有执行完毕,无法释放当前持有的锁,被调用的原子性方法又需要此锁,导致线程被阻塞。

例:

public class Test {
    Lock locka = new Lock();
    ReentrantLock lock = new ReentrantLock();
    public void a() throws InterruptedException {
        locka.lock();
        System.out.println("aaaa");
        b();
        locka.unlock();
    }

    public void b() throws InterruptedException {
        locka.lock();
        System.out.println("执行方法b");
        locka.unlock();
    }

    public static void main(String[] args) throws InterruptedException {
       Test test = new Test();
       test.a();
    }

}

方法a加了锁,在执行方法时调用方法b,方法b必须持有锁才能执行,但是方法a还没执行完,无法释放持有的锁,导致方法b无法获得锁,导致出现了思索现象。

解决方法:使用可重入锁

方法1:synchronized

public class Test {
    Lock locka = new Lock();
    ReentrantLock lock = new ReentrantLock();
    public synchronized void a() throws InterruptedException {
        System.out.println("aaaa");
        b();
    }

    public void b() throws InterruptedException {
        System.out.println("执行方法b");
    }

    public static void main(String[] args) throws InterruptedException {
       Test test = new Test();
       test.a();
    }

}

方法2:可重入锁ReentrantLock

public class Test {
    Lock locka = new Lock();
    ReentrantLock lock = new ReentrantLock();
    public synchronized void a() throws InterruptedException {
        lock.lock();
        System.out.println("aaaa");
        b();
        lock.unlock();
    }

    public void b() throws InterruptedException {
        lock.lock();
        System.out.println("执行方法b");
        lock.unlock();
    }

需要注意的是,ReenTrantLock上几次锁,就不要释放几次锁,即lock()方法和unlock()方法是成对出现的,不然会出现资源消耗异常

Thread.join():等待线程,谁调用就等待谁,等待者为当前线程。等待期间

Object.wait();线程挂起,释放对象锁,等待被唤醒,持有资源。

Object.notify():唤醒之前持有相同对象锁的线程,被唤醒的线程继续竞争对象锁,唤醒者必须释放锁,被唤醒者才有机会持有锁。

笔记:

1.若不同线程在不同同步代码块中持有相同对象的锁,那么该线程对变量的改变对于持有相同锁的线程来说是透明可见的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值