实例解析:Java多线程并发中的锁问题

原创 深藏阁楼爱情的钟 2024-12-09 06:21 113阅读 0赞

在Java的多线程编程中,锁(Lock)问题是非常常见且重要的。以下是关于锁问题的一些实例解析:

  1. 独占锁(Synchronized)

    • 示例:有一个银行账户对象,多个线程可能尝试增加或减少账户金额。

      1. class BankAccount {
      2. private double balance = 0;
      3. synchronized void deposit(double amount) {
      4. balance += amount;
      5. notifyAll(); // 当余额改变后通知所有等待的线程
      6. }
      7. synchronized void withdraw(double amount) {
      8. if (amount > balance) {
      9. System.out.println("Insufficient balance");
      10. return;
      11. }
      12. balance -= amount;
      13. notifyAll();
      14. }
      15. }
  2. 共享锁(ReentrantLock)

    • 示例:多个线程可能需要同时访问和修改一个对象的某些属性。
      ```java
      import java.util.concurrent.locks.Lock;
      import java.util.concurrent.locks.ReentrantLock;

    class SharedResource {

    1. private int count = 0;
    2. Lock lock = new ReentrantLock();
    3. public synchronized void increment() {
    4. count++;
    5. lock.unlock(); // 执行完操作后解锁,其他线程可以进入
    6. lock.acquire(); // 获得锁后,再次锁定资源,防止其他线程修改
    7. System.out.println("Incremented count: " + count);
    8. }
    9. public synchronized void decrement() {
    10. if (count > 0) {
    11. count--;
    12. lock.unlock();
    13. lock.acquire();
    14. System.out.println("Decremented count: " + count);
    15. } else {
    16. System.out.println("Can't decrement count, it's already 0");
    17. }
    18. }

    }
    ```

  3. 死锁(Deadlock)

    • 示例:两个线程A和B,A持有资源1,B持有资源2,但它们都无法完成操作。

      1. class DeadlockThread {
      2. private Resource resource1 = new Resource(1);
      3. private Resource resource2 = new Resource(2);
      4. public void acquireResource1() {
      5. synchronized (resource1) {
      6. if (!resource1.isAvailable()) {
      7. System.out.println("Can't acquire resource 1, it's already taken");
      8. return;
      9. }
      10. resource1.use();
      11. System.out.println("Acquired resource 1");
      12. notifyAll(); // 通知等待的线程资源可用
      13. }
      14. }
      15. public void acquireResource2() {
      16. synchronized (resource2) {
      17. if (!resource2.isAvailable())) {
      18. System.out.println("Can't acquire resource 2, it's already taken");
      19. return;
      20. }
      21. resource2.use();
      22. System.out.println("Acquired resource 2");
      23. notifyAll(); // 通知等待的线程资源可用
      24. }
      25. }
      26. public void run() {
      27. try {
      28. acquireResource1();
      29. acquireResource2();
      30. System.out.println("Both resources acquired, executing operation...");
      31. Thread.sleep(3000); // 模拟耗时操作
      32. System.out.println("Operation completed.");
      33. } catch (InterruptedException e) {
      34. System.out.println("Interrupted during resource acquisition or execution");
      35. e.printStackTrace();
      36. }
      37. finally {
      38. System.out.println("资源释放完毕,线程退出...");
      39. }
      40. }
      41. }

      在上述例子中,A和B两个线程分别持有资源1和2,并且它们都无法完成自己的操作(即没有互斥)。这就导致了死锁的发生。

文章版权声明:注明蒲公英云原创文章,转载或复制请以超链接形式并注明出处。

发表评论

表情:
评论列表 (有 0 条评论,113人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Java线并发问题解析实例

    在Java编程中,多线程并发问题通常涉及到资源竞争、死锁、活锁等问题。这里我们通过一个具体的实例来解析这些问题。 **案例:银行取款机** 场景:假设银行的自动取款机(AT