Java-互斥锁&死锁&释放锁

互斥锁

        互斥锁(Mutex Lock)是一种同步机制,用于确保在任何时刻只有一个线程可以访问特定的代码段(临界区),从而防止数据竞争和不一致性。

使用方法

  • 在Java中,可以使用synchronized关键字或ReentrantLock类来实现互斥锁。
  • 使用lock()方法获取锁,使用unlock()方法释放锁。

特点

  • 确保线程安全,防止多个线程同时访问共享资源。
  • 简单易用,但需要注意锁的粒度和性能影响。

示例:

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class MutexExample {
    private static int counter = 0; // 定义一个共享资源,初始值为0
    private static Lock lock = new ReentrantLock(); // 定义一个可重入锁

    public static void main(String[] args) {
        Thread[] threads = new Thread[10]; // 创建一个包含10个线程的数组

        for (int i = 0; i < 10; i++) {
            threads[i] = new Thread(() -> {
                lock.lock(); // 获取锁,确保同一时间只有一个线程可以执行下面的代码
                try {
                    counter++; // 访问并修改共享资源
                    System.out.println("Counter value: " + counter); // 打印当前计数器的值
                } finally {
                    lock.unlock(); // 释放锁,确保锁一定会被释放,避免死锁
                }
            });
            threads[i].start(); // 启动线程
        }

        for (int i = 0; i < 10; i++) {
            try {
                threads[i].join(); // 等待所有线程执行完毕
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

 线程死锁

         线程死锁(Deadlock)是指两个或多个线程互相等待对方释放资源,导致所有相关线程都无法继续执行的状态。

产生条件

  • 互斥条件:资源不能被共享,一次只能被一个线程使用。
  • 占有并等待:线程已经占有至少一个资源,并等待获取其他线程占有的资源。
  • 不可抢占:资源不能被强制抢占,只能由占有它的线程主动释放。
  • 循环等待:存在一个线程资源的循环链,每个线程都在等待链中下一个线程占有的资源。

示例

public class DeadlockExample {
    private static Object lock1 = new Object(); // 定义第一个锁对象
    private static Object lock2 = new Object(); // 定义第二个锁对象

    public static void main(String[] args) {
        Thread thread1 = new Thread(() -> {
            synchronized (lock1) { // 获取第一个锁
                System.out.println("Thread 1: Holding lock 1...");
                try { Thread.sleep(10); } catch (InterruptedException e) {} // 模拟一些工作
                System.out.println("Thread 1: Waiting for lock 2...");
                synchronized (lock2) { // 尝试获取第二个锁
                    System.out.println("Thread 1: Holding lock 1 & 2...");
                }
            }
        });

        Thread thread2 = new Thread(() -> {
            synchronized (lock2) { // 获取第二个锁
                System.out.println("Thread 2: Holding lock 2...");
                try { Thread.sleep(10); } catch (InterruptedException e) {} // 模拟一些工作
                System.out.println("Thread 2: Waiting for lock 1...");
                synchronized (lock1) { // 尝试获取第一个锁
                    System.out.println("Thread 2: Holding lock 1 & 2...");
                }
            }
        });

        thread1.start(); // 启动第一个线程
        thread2.start(); // 启动第二个线程
    }
}

释放锁

        释放锁是指线程在完成对共享资源的访问后,主动将锁释放,以便其他线程可以获取锁并访问资源。

使用方法

  • 在Java中,使用unlock()方法释放锁。
  • 确保在finally块中释放锁,以防止资源泄漏。

特点

  • 确保资源能够被其他线程访问,避免资源被永久占用。
  • 需要谨慎处理,确保锁的释放顺序正确,避免死锁。

示例

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ReleaseLockExample {
    private static Lock lock = new ReentrantLock(); // 定义一个可重入锁

    public static void main(String[] args) {
        lock.lock(); // 获取锁
        try {
            // 访问共享资源
            System.out.println("Accessing shared resource...");
        } finally {
            lock.unlock(); // 释放锁,确保锁一定会被释放,避免死锁
            System.out.println("Lock released.");
        }
    }
}

总结

        理解这些是很重要的,在开发中我们要避免死锁,谨慎处理线程。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值