解决Java并发编程常见问题:锁竞争及死锁案例

原创 青旅半醒 2024-09-23 11:12 163阅读 0赞

在Java并发编程中,常见的问题包括锁竞争和死锁。下面我会分别给出这两个问题的案例。

锁竞争案例

场景一:线程池中的资源争抢

  1. import java.util.concurrent.Executors;
  2. import java.util.concurrent.Lock;
  3. public class LockConflict {
  4. private final Lock lock = new ReentrantLock();
  5. public void concurrentAccess() {
  6. ExecutorService executor = Executors.newFixedThreadPool(10);
  7. for (int i = 0; i < 1000; i++) {
  8. executor.submit(() -> {
  9. try {
  10. lock.lock();
  11. // 这里是竞争的资源
  12. Thread.sleep(50); // 模拟耗时操作
  13. } catch (InterruptedException e) {
  14. e.printStackTrace();
  15. } finally {
  16. lock.unlock();
  17. }
  18. }));
  19. }
  20. executor.shutdown();
  21. }
  22. public static void main(String[] args) {
  23. LockConflict example = new LockConflict();
  24. example.concurrentAccess();
  25. }
  26. }

场景二:多个线程同时修改共享数据

  1. import java.util.concurrent.atomic.AtomicInteger;
  2. public class LockConflictAtomicVariable {
  3. private AtomicInteger count = new AtomicInteger(0);
  4. public void concurrentUpdate() {
  5. for (int i = 0; i < 1000; i++) {
  6. Thread thread = new Thread(() -> {
  7. try {
  8. // 随机选择更新操作
  9. int updateType = Math.random() >= 0.5 ? 1 : 2;
  10. if (updateType == 1) { // 增加计数器值
  11. count.incrementAndGet();
  12. } else if (updateType == 2) { // 减少计数器值
  13. count.decrementAndGet();
  14. }
  15. } catch (Exception e) {
  16. e.printStackTrace();
  17. } finally {
  18. // 模拟耗时操作
  19. try {
  20. Thread.sleep(50);
  21. } catch (InterruptedException e) {
  22. e.printStackTrace();
  23. }
  24. }
  25. }));
  26. thread.start();
  27. }
  28. }
  29. public static void main(String[] args) {
  30. LockConflictAtomicVariable example = new LockConflictAtomicVariable();
  31. example.concurrentUpdate();
  32. System.out.println("Final count: " + example.count.get()); // 输出最终计数结果
  33. }
  34. }

死锁案例

场景一:银行贷款系统中的死锁

  1. import java.util.concurrent.locks.Lock;
  2. import java.util.concurrent.locks.ReentrantLock;
  3. public class BankLoanSystemDeadlock {
  4. private final Lock loan1Lock = new ReentrantLock();
  5. private final Lock loan2Lock = new ReentrantLock();
  6. public void processLoans() throws InterruptedException {
  7. // 贷款A的请求
  8. loan1Lock.lock();
  9. try {
  10. // 确认贷款B的请求尚未被获取
  11. if (!loan2Lock.isHeldByAnyThread()) {
  12. System.out.println("批准贷款 A (金额:1000)}");
  13. // 处理贷款并释放锁
  14. processLoan(1000);
  15. loan1Lock.unlock();
  16. } else {
  17. System.out.println("拒绝贷款A,因为贷款B正在处理中。");
  18. loan1Lock.unlock();
  19. }
  20. } catch (Exception e) {
  21. e.printStackTrace();
  22. loan1Lock.unlock(); // 如果出现异常,释放锁
  23. }
  24. }
  25. private void processLoan(int loanAmount) {
  26. // 贷款B的请求
  27. loan2Lock.lock();
  28. try {
  29. System.out.println("批准贷款 B (金额: " + loanAmount + ")");
  30. // 处理贷款并释放锁
  31. payOffLoans(loanAmount);
  32. loan2Lock.unlock();
  33. } catch (Exception e) {
  34. e.printStackTrace();
  35. loan2Lock.unlock(); // 如果出现异常,释放锁
  36. }
  37. }
  38. private void payOffLoans(int loanAmount) {
  39. System.out.println("偿还贷款:" + loanAmount);
  40. }
  41. public static void main(String[] args) {
  42. BankLoanSystemDeadlock example = new BankLoanSystemDeadlock();
  43. example.processLoans(); // 调用处理贷款的方法
  44. }
  45. }

在这个场景中,两个线程分别在请求贷款A和B时竞争锁。如果一个线程请求贷款A并在得到锁后请求贷款B,另一个线程可能会因为锁被获取而一直等待,从而导致死锁。

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

发表评论

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

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

相关阅读